Coverage Report

Created: 2026-10-28 06:12

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/work/dav1d/src/decode.c
Line
Count
Source
1
/*
2
 * Copyright © 2018-2021, 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 <errno.h>
31
#include <limits.h>
32
#include <string.h>
33
#include <stdio.h>
34
#include <inttypes.h>
35
36
#include "dav1d/data.h"
37
38
#include "common/frame.h"
39
#include "common/intops.h"
40
41
#include "src/ctx.h"
42
#include "src/decode.h"
43
#include "src/dequant_tables.h"
44
#include "src/env.h"
45
#include "src/filmgrain.h"
46
#include "src/log.h"
47
#include "src/qm.h"
48
#include "src/recon.h"
49
#include "src/ref.h"
50
#include "src/tables.h"
51
#include "src/thread_task.h"
52
#include "src/warpmv.h"
53
54
static void init_quant_tables(const Dav1dSequenceHeader *const seq_hdr,
55
                              const Dav1dFrameHeader *const frame_hdr,
56
                              const int qidx, uint16_t (*dq)[3][2])
57
36.1k
{
58
204k
    for (int i = 0; i < (frame_hdr->segmentation.enabled ? 8 : 1); i++) {
59
168k
        const int yac = frame_hdr->segmentation.enabled ?
60
151k
            iclip_u8(qidx + frame_hdr->segmentation.seg_data.d[i].delta_q) : qidx;
61
168k
        const int ydc = iclip_u8(yac + frame_hdr->quant.ydc_delta);
62
168k
        const int uac = iclip_u8(yac + frame_hdr->quant.uac_delta);
63
168k
        const int udc = iclip_u8(yac + frame_hdr->quant.udc_delta);
64
168k
        const int vac = iclip_u8(yac + frame_hdr->quant.vac_delta);
65
168k
        const int vdc = iclip_u8(yac + frame_hdr->quant.vdc_delta);
66
67
168k
        dq[i][0][0] = dav1d_dq_tbl[seq_hdr->hbd][ydc][0];
68
168k
        dq[i][0][1] = dav1d_dq_tbl[seq_hdr->hbd][yac][1];
69
168k
        dq[i][1][0] = dav1d_dq_tbl[seq_hdr->hbd][udc][0];
70
168k
        dq[i][1][1] = dav1d_dq_tbl[seq_hdr->hbd][uac][1];
71
168k
        dq[i][2][0] = dav1d_dq_tbl[seq_hdr->hbd][vdc][0];
72
168k
        dq[i][2][1] = dav1d_dq_tbl[seq_hdr->hbd][vac][1];
73
168k
    }
74
36.1k
}
75
76
static int read_mv_component_diff(MsacContext *const msac,
77
                                  CdfMvComponent *const mv_comp,
78
                                  const int mv_prec)
79
672k
{
80
672k
    const int sign = dav1d_msac_decode_bool_adapt(msac, mv_comp->sign);
81
672k
    const int cl = dav1d_msac_decode_symbol_adapt16(msac, mv_comp->classes, 10);
82
672k
    int up, fp = 3, hp = 1;
83
84
672k
    if (!cl) {
85
103k
        up = dav1d_msac_decode_bool_adapt(msac, mv_comp->class0);
86
103k
        if (mv_prec >= 0) {  // !force_integer_mv
87
53.1k
            fp = dav1d_msac_decode_symbol_adapt4(msac, mv_comp->class0_fp[up], 3);
88
53.1k
            if (mv_prec > 0) // allow_high_precision_mv
89
16.1k
                hp = dav1d_msac_decode_bool_adapt(msac, mv_comp->class0_hp);
90
53.1k
        }
91
569k
    } else {
92
569k
        up = 1 << cl;
93
6.04M
        for (int n = 0; n < cl; n++)
94
5.47M
            up |= dav1d_msac_decode_bool_adapt(msac, mv_comp->classN[n]) << n;
95
569k
        if (mv_prec >= 0) {  // !force_integer_mv
96
16.8k
            fp = dav1d_msac_decode_symbol_adapt4(msac, mv_comp->classN_fp, 3);
97
16.8k
            if (mv_prec > 0) // allow_high_precision_mv
98
6.09k
                hp = dav1d_msac_decode_bool_adapt(msac, mv_comp->classN_hp);
99
16.8k
        }
100
569k
    }
101
102
672k
    const int diff = ((up << 3) | (fp << 1) | hp) + 1;
103
104
672k
    return sign ? -diff : diff;
105
672k
}
106
107
static void read_mv_residual(Dav1dTileState *const ts, mv *const ref_mv,
108
                             const int mv_prec)
109
368k
{
110
368k
    MsacContext *const msac = &ts->msac;
111
368k
    const enum MVJoint mv_joint =
112
368k
        dav1d_msac_decode_symbol_adapt4(msac, ts->cdf.mv.joint, N_MV_JOINTS - 1);
113
368k
    if (mv_joint & MV_JOINT_V)
114
337k
        ref_mv->y += read_mv_component_diff(msac, &ts->cdf.mv.comp[0], mv_prec);
115
368k
    if (mv_joint & MV_JOINT_H)
116
335k
        ref_mv->x += read_mv_component_diff(msac, &ts->cdf.mv.comp[1], mv_prec);
117
368k
}
118
119
static void read_tx_tree(Dav1dTaskContext *const t,
120
                         const enum RectTxfmSize from,
121
                         const int depth, uint16_t *const masks,
122
                         const int x_off, const int y_off)
123
135k
{
124
135k
    const Dav1dFrameContext *const f = t->f;
125
135k
    const int bx4 = t->bx & 31, by4 = t->by & 31;
126
135k
    const TxfmInfo *const t_dim = &dav1d_txfm_dimensions[from];
127
135k
    const int txw = t_dim->lw, txh = t_dim->lh;
128
135k
    int is_split;
129
130
135k
    if (depth < 2 && from > (int) TX_4X4) {
131
119k
        const int cat = 2 * (TX_64X64 - t_dim->max) - depth;
132
119k
        const int a = t->a->tx[bx4] < txw;
133
119k
        const int l = t->l.tx[by4] < txh;
134
135
119k
        is_split = dav1d_msac_decode_bool_adapt(&t->ts->msac,
136
119k
                       t->ts->cdf.m.txpart[cat][a + l]);
137
119k
        if (is_split)
138
31.8k
            masks[depth] |= 1 << (y_off * 4 + x_off);
139
119k
    } else {
140
15.9k
        is_split = 0;
141
15.9k
    }
142
143
135k
    if (is_split && t_dim->max > TX_8X8) {
144
23.3k
        const enum RectTxfmSize sub = t_dim->sub;
145
23.3k
        const TxfmInfo *const sub_t_dim = &dav1d_txfm_dimensions[sub];
146
23.3k
        const int txsw = sub_t_dim->w, txsh = sub_t_dim->h;
147
148
23.3k
        read_tx_tree(t, sub, depth + 1, masks, x_off * 2 + 0, y_off * 2 + 0);
149
23.3k
        t->bx += txsw;
150
23.3k
        if (txw >= txh && t->bx < f->bw)
151
15.8k
            read_tx_tree(t, sub, depth + 1, masks, x_off * 2 + 1, y_off * 2 + 0);
152
23.3k
        t->bx -= txsw;
153
23.3k
        t->by += txsh;
154
23.3k
        if (txh >= txw && t->by < f->bh) {
155
12.3k
            read_tx_tree(t, sub, depth + 1, masks, x_off * 2 + 0, y_off * 2 + 1);
156
12.3k
            t->bx += txsw;
157
12.3k
            if (txw >= txh && t->bx < f->bw)
158
4.93k
                read_tx_tree(t, sub, depth + 1, masks,
159
4.93k
                             x_off * 2 + 1, y_off * 2 + 1);
160
12.3k
            t->bx -= txsw;
161
12.3k
        }
162
23.3k
        t->by -= txsh;
163
111k
    } else {
164
111k
        dav1d_memset_pow2[t_dim->lw](&t->a->tx[bx4], is_split ? TX_4X4 : txw);
165
111k
        dav1d_memset_pow2[t_dim->lh](&t->l.tx[by4], is_split ? TX_4X4 : txh);
166
111k
    }
167
135k
}
168
169
508k
static int neg_deinterleave(int diff, int ref, int max) {
170
508k
    if (!ref) return diff;
171
278k
    if (ref >= (max - 1)) return max - diff - 1;
172
192k
    if (2 * ref < max) {
173
114k
        if (diff <= 2 * ref) {
174
90.6k
            if (diff & 1)
175
13.3k
                return ref + ((diff + 1) >> 1);
176
77.3k
            else
177
77.3k
                return ref - (diff >> 1);
178
90.6k
        }
179
23.8k
        return diff;
180
114k
    } else {
181
78.4k
        if (diff <= 2 * (max - ref - 1)) {
182
64.6k
            if (diff & 1)
183
10.1k
                return ref + ((diff + 1) >> 1);
184
54.4k
            else
185
54.4k
                return ref - (diff >> 1);
186
64.6k
        }
187
13.7k
        return max - (diff + 1);
188
78.4k
    }
189
192k
}
190
191
static void find_matching_ref(const Dav1dTaskContext *const t,
192
                              const enum EdgeFlags intra_edge_flags,
193
                              const int bw4, const int bh4,
194
                              const int w4, const int h4,
195
                              const int have_left, const int have_top,
196
                              const int ref, uint64_t masks[2])
197
46.6k
{
198
46.6k
    /*const*/ refmvs_block *const *r = &t->rt.r[(t->by & 31) + 5];
199
46.6k
    int count = 0;
200
46.6k
    int have_topleft = have_top && have_left;
201
46.6k
    int have_topright = imax(bw4, bh4) < 32 &&
202
45.9k
                        have_top && t->bx + bw4 < t->ts->tiling.col_end &&
203
16.4k
                        (intra_edge_flags & EDGE_I444_TOP_HAS_RIGHT);
204
205
83.1k
#define bs(rp) dav1d_block_dimensions[(rp)->bs]
206
90.6k
#define matches(rp) ((rp)->ref.ref[0] == ref + 1 && (rp)->ref.ref[1] == -1)
207
208
46.6k
    if (have_top) {
209
30.1k
        const refmvs_block *r2 = &r[-1][t->bx];
210
30.1k
        if (matches(r2)) {
211
22.2k
            masks[0] |= 1;
212
22.2k
            count = 1;
213
22.2k
        }
214
30.1k
        int aw4 = bs(r2)[0];
215
30.1k
        if (aw4 >= bw4) {
216
25.1k
            const int off = t->bx & (aw4 - 1);
217
25.1k
            if (off) have_topleft = 0;
218
25.1k
            if (aw4 - off > bw4) have_topright = 0;
219
25.1k
        } else {
220
5.02k
            unsigned mask = 1 << aw4;
221
10.1k
            for (int x = aw4; x < w4; x += aw4) {
222
5.07k
                r2 += aw4;
223
5.07k
                if (matches(r2)) {
224
3.05k
                    masks[0] |= mask;
225
3.05k
                    if (++count >= 8) return;
226
3.05k
                }
227
5.07k
                aw4 = bs(r2)[0];
228
5.07k
                mask <<= aw4;
229
5.07k
            }
230
5.02k
        }
231
30.1k
    }
232
46.6k
    if (have_left) {
233
32.8k
        /*const*/ refmvs_block *const *r2 = r;
234
32.8k
        if (matches(&r2[0][t->bx - 1])) {
235
23.6k
            masks[1] |= 1;
236
23.6k
            if (++count >= 8) return;
237
23.6k
        }
238
32.8k
        int lh4 = bs(&r2[0][t->bx - 1])[1];
239
32.8k
        if (lh4 >= bh4) {
240
27.5k
            if (t->by & (lh4 - 1)) have_topleft = 0;
241
27.5k
        } else {
242
5.25k
            unsigned mask = 1 << lh4;
243
10.3k
            for (int y = lh4; y < h4; y += lh4) {
244
5.09k
                r2 += lh4;
245
5.09k
                if (matches(&r2[0][t->bx - 1])) {
246
3.01k
                    masks[1] |= mask;
247
3.01k
                    if (++count >= 8) return;
248
3.01k
                }
249
5.08k
                lh4 = bs(&r2[0][t->bx - 1])[1];
250
5.08k
                mask <<= lh4;
251
5.08k
            }
252
5.25k
        }
253
32.8k
    }
254
46.6k
    if (have_topleft && matches(&r[-1][t->bx - 1])) {
255
6.72k
        masks[1] |= 1ULL << 32;
256
6.72k
        if (++count >= 8) return;
257
6.72k
    }
258
46.5k
    if (have_topright && matches(&r[-1][t->bx + bw4])) {
259
4.51k
        masks[0] |= 1ULL << 32;
260
4.51k
    }
261
46.5k
#undef matches
262
46.5k
}
263
264
static void derive_warpmv(const Dav1dTaskContext *const t,
265
                          const int bw4, const int bh4,
266
                          const uint64_t masks[2], const union mv mv,
267
                          Dav1dWarpedMotionParams *const wmp)
268
2.14k
{
269
2.14k
    int pts[8][2 /* in, out */][2 /* x, y */], np = 0;
270
2.14k
    /*const*/ refmvs_block *const *r = &t->rt.r[(t->by & 31) + 5];
271
272
4.27k
#define add_sample(dx, dy, sx, sy, rp) do { \
273
4.27k
    pts[np][0][0] = 16 * (2 * dx + sx * bs(rp)[0]) - 8; \
274
4.27k
    pts[np][0][1] = 16 * (2 * dy + sy * bs(rp)[1]) - 8; \
275
4.27k
    pts[np][1][0] = pts[np][0][0] + (rp)->mv.mv[0].x; \
276
4.27k
    pts[np][1][1] = pts[np][0][1] + (rp)->mv.mv[0].y; \
277
4.27k
    np++; \
278
4.27k
} while (0)
279
280
    // use masks[] to find the projectable motion vectors in the edges
281
2.14k
    if ((unsigned) masks[0] == 1 && !(masks[1] >> 32)) {
282
547
        const int off = t->bx & (bs(&r[-1][t->bx])[0] - 1);
283
547
        add_sample(-off, 0, 1, -1, &r[-1][t->bx]);
284
2.39k
    } else for (unsigned off = 0, xmask = (uint32_t) masks[0]; np < 8 && xmask;) { // top
285
800
        const int tz = ctz(xmask);
286
800
        off += tz;
287
800
        xmask >>= tz;
288
800
        add_sample(off, 0, 1, -1, &r[-1][t->bx + off]);
289
800
        xmask &= ~1;
290
800
    }
291
2.14k
    if (np < 8 && masks[1] == 1) {
292
915
        const int off = t->by & (bs(&r[0][t->bx - 1])[1] - 1);
293
915
        add_sample(0, -off, -1, 1, &r[-off][t->bx - 1]);
294
2.01k
    } else for (unsigned off = 0, ymask = (uint32_t) masks[1]; np < 8 && ymask;) { // left
295
787
        const int tz = ctz(ymask);
296
787
        off += tz;
297
787
        ymask >>= tz;
298
787
        add_sample(0, off, -1, 1, &r[off][t->bx - 1]);
299
787
        ymask &= ~1;
300
787
    }
301
2.14k
    if (np < 8 && masks[1] >> 32) // top/left
302
654
        add_sample(0, 0, -1, -1, &r[-1][t->bx - 1]);
303
2.14k
    if (np < 8 && masks[0] >> 32) // top/right
304
571
        add_sample(bw4, 0, 1, -1, &r[-1][t->bx + bw4]);
305
2.14k
    assert(np > 0 && np <= 8);
306
2.14k
#undef bs
307
308
    // select according to motion vector difference against a threshold
309
2.14k
    int mvd[8], ret = 0;
310
2.14k
    const int thresh = 4 * iclip(imax(bw4, bh4), 4, 28);
311
6.41k
    for (int i = 0; i < np; i++) {
312
4.27k
        mvd[i] = abs(pts[i][1][0] - pts[i][0][0] - mv.x) +
313
4.27k
                 abs(pts[i][1][1] - pts[i][0][1] - mv.y);
314
4.27k
        if (mvd[i] > thresh)
315
1.64k
            mvd[i] = -1;
316
2.63k
        else
317
2.63k
            ret++;
318
4.27k
    }
319
2.14k
    if (!ret) {
320
676
        ret = 1;
321
1.70k
    } else for (int i = 0, j = np - 1, k = 0; k < np - ret; k++, i++, j--) {
322
811
        while (mvd[i] != -1) i++;
323
980
        while (mvd[j] == -1) j--;
324
509
        assert(i != j);
325
509
        if (i > j) break;
326
        // replace the discarded samples;
327
244
        mvd[i] = mvd[j];
328
244
        memcpy(pts[i], pts[j], sizeof(*pts));
329
244
    }
330
331
2.14k
    if (!dav1d_find_affine_int(pts, ret, bw4, bh4, mv, wmp, t->bx, t->by) &&
332
1.93k
        !dav1d_get_shear_params(wmp))
333
1.68k
    {
334
1.68k
        wmp->type = DAV1D_WM_TYPE_AFFINE;
335
1.68k
    } else
336
460
        wmp->type = DAV1D_WM_TYPE_IDENTITY;
337
2.14k
}
338
339
48.2k
static inline int findoddzero(const uint8_t *buf, int len) {
340
51.3k
    for (int n = 0; n < len; n++)
341
49.6k
        if (!buf[n * 2]) return 1;
342
1.66k
    return 0;
343
48.2k
}
344
345
// Resolve a decoded rank (color_idx) to a palette entry, given the ordered
346
// priority candidates p[0..prio_count-1] and the bitmask of values already
347
// used by those candidates. Ranks below prio_count select a priority
348
// candidate directly; higher ranks select the (rank - prio_count)th value
349
// (counting from 0) that is not present in mask, in ascending order.
350
static inline int resolve_pal_color(const int color_idx, const uint8_t *const p,
351
                                    const int prio_count, unsigned mask)
352
1.18M
{
353
1.18M
    if (color_idx < prio_count)
354
988k
        return p[color_idx];
355
196k
    unsigned rank = color_idx - prio_count + (mask & 1);
356
196k
    rank += ((mask >> 1) & 1) & (rank > 0);
357
    // Unset-bit positions minus their ranks, packed in 2-bit fields.
358
    // Mask bits 0 and 1 are cleared and compensated in rank.
359
    // At most three priority colors keep each offset within 0..3.
360
196k
    static const uint8_t free_offsets2[] = {
361
196k
        0x00, 0x00, 0x50, 0x15, 0x40, 0x15, 0xa0, 0x0a, 0x00, 0x15, 0x90, 0x0a,
362
196k
        0x80, 0x0a, 0xf0, 0x03, 0x00, 0x14, 0x50, 0x0a, 0x40, 0x0a, 0xe0, 0x03,
363
196k
        0x00, 0x0a, 0xd0, 0x03, 0xc0, 0x03, 0x00, 0x00, 0x00, 0x10, 0x50, 0x09,
364
196k
        0x40, 0x09, 0xa0, 0x03, 0x00, 0x09, 0x90, 0x03, 0x80, 0x03, 0x00, 0x00,
365
196k
        0x00, 0x08, 0x50, 0x03, 0x40, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
366
196k
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x05, 0x40, 0x05, 0xa0, 0x02,
367
196k
        0x00, 0x05, 0x90, 0x02, 0x80, 0x02, 0x00, 0x00, 0x00, 0x04, 0x50, 0x02,
368
196k
        0x40, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
369
196k
        0x00, 0x00, 0x50, 0x01, 0x40, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
370
196k
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
371
196k
    };
372
196k
    const unsigned byte_idx = 2 * (mask >> 2) + (rank >> 2);
373
196k
    assert(byte_idx < sizeof(free_offsets2));
374
196k
    return rank + ((free_offsets2[byte_idx] >> (2 * (rank & 3))) & 3);
375
196k
}
376
377
static void read_pal_indices(Dav1dTaskContext *const t,
378
                             uint8_t *const pal_idx,
379
                             const int pal_sz, const int pl,
380
                             const int w4, const int h4,
381
                             const int bw4, const int bh4)
382
8.31k
{
383
8.31k
    Dav1dTileState *const ts = t->ts;
384
8.31k
    const ptrdiff_t stride = bw4 * 4;
385
8.31k
    assert(pal_idx);
386
8.31k
    uint8_t *const pal_tmp = t->scratch.pal_idx_uv;
387
8.31k
    pal_tmp[0] = dav1d_msac_decode_uniform(&ts->msac, pal_sz);
388
8.31k
    uint16_t (*const color_map_cdf)[8] =
389
8.31k
        ts->cdf.m.color_map[pl][pal_sz - 2];
390
391
8.31k
    if (pal_sz == 2) {
392
        // Binary palette: ctx 1 is unreachable (needs 3 distinct neighbours),
393
        // and resolve always toggles the single priority value. Use a bool
394
        // decode instead of a symbol decode. ctx formula collapses to:
395
        // border -> 0, interior -> 2 + same_t_l + (same_t_l & same_t_tl)
396
56.2k
        for (int i = 1; i < 4 * (w4 + h4) - 1; i++) {
397
54.2k
            const int first = imin(i, w4 * 4 - 1);
398
54.2k
            const int last = imax(0, i - h4 * 4 + 1);
399
54.2k
            int have_top = i > first;
400
54.2k
            const uint8_t *pal_row = pal_tmp + first + (i - first) * stride;
401
486k
            for (int j = first; j >= last; have_top = 1, j--, pal_row += stride - 1) {
402
432k
                const int have_left = j > 0;
403
432k
                int ctx, p0;
404
432k
                if (!have_left) {
405
25.0k
                    ctx = 0;
406
25.0k
                    p0 = pal_row[-stride];
407
407k
                } else if (!have_top) {
408
29.2k
                    ctx = 0;
409
29.2k
                    p0 = pal_row[-1];
410
377k
                } else {
411
377k
                    const int l = pal_row[-1], tp = pal_row[-stride];
412
377k
                    const int tl = pal_row[-(stride + 1)];
413
377k
                    const int same_t_l = tp == l;
414
377k
                    const int same_t_tl = tp == tl;
415
377k
                    ctx = 2 + same_t_l + (same_t_l & same_t_tl);
416
377k
                    p0 = same_t_l ? tp : tl;
417
377k
                }
418
432k
                const int bit = dav1d_msac_decode_bool_adapt(
419
432k
                    &ts->msac, color_map_cdf[ctx]);
420
432k
                pal_tmp[(i - j) * stride + j] = bit ^ p0;
421
432k
            }
422
54.2k
        }
423
1.93k
        t->c->pal_dsp.pal_idx_finish(pal_idx, pal_tmp, bw4 * 4, bh4 * 4,
424
1.93k
                                     w4 * 4, h4 * 4);
425
1.93k
        return;
426
1.93k
    }
427
428
6.37k
    unsigned (*const symbol_adapt)(MsacContext *, uint16_t *, size_t) =
429
6.37k
        pal_sz <= 4 ? dav1d_msac_decode_symbol_adapt4 : dav1d_msac_decode_symbol_adapt8;
430
431
173k
    for (int i = 1; i < 4 * (w4 + h4) - 1; i++) {
432
        // top/left-to-bottom/right diagonals ("wave-front")
433
167k
        const int first = imin(i, w4 * 4 - 1);
434
167k
        const int last = imax(0, i - h4 * 4 + 1);
435
167k
        int have_top = i > first;
436
167k
        const uint8_t *pal_row = pal_tmp + first + (i - first) * stride;
437
1.35M
        for (int j = first; j >= last; have_top = 1, j--, pal_row += stride - 1) {
438
1.18M
            const int have_left = j > 0;
439
1.18M
            uint8_t p[3];
440
1.18M
            unsigned mask;
441
1.18M
            int ctx, prio_count;
442
1.18M
            if (!have_left) {
443
78.1k
                ctx = 0; prio_count = 1;
444
78.1k
                p[0] = pal_row[-stride];
445
78.1k
                mask = 1u << p[0];
446
1.10M
            } else if (!have_top) {
447
89.3k
                ctx = 0; prio_count = 1;
448
89.3k
                p[0] = pal_row[-1];
449
89.3k
                mask = 1u << p[0];
450
1.01M
            } else {
451
1.01M
                const int l = pal_row[-1], tp = pal_row[-stride];
452
1.01M
                const int tl = pal_row[-(stride + 1)];
453
1.01M
                const int same_t_l = tp == l;
454
1.01M
                const int same_t_tl = tp == tl;
455
1.01M
                const int same_l_tl = l == tl;
456
1.01M
                if (same_t_l & same_t_tl) {
457
470k
                    ctx = 4; prio_count = 1;
458
470k
                    p[0] = tp; mask = 1u << tp;
459
546k
                } else if (same_t_l) {
460
33.5k
                    ctx = 3; prio_count = 2;
461
33.5k
                    p[0] = tp; p[1] = tl;
462
33.5k
                    mask = (1u << tp) | (1u << tl);
463
512k
                } else if (same_t_tl | same_l_tl) {
464
401k
                    ctx = 2; prio_count = 2;
465
401k
                    p[0] = tl; p[1] = same_t_tl ? l : tp;
466
401k
                    mask = (1u << tl) | (1u << p[1]);
467
401k
                } else {
468
111k
                    ctx = 1; prio_count = 3;
469
111k
                    p[0] = imin(tp, l); p[1] = imax(tp, l); p[2] = tl;
470
111k
                    mask = (1u << tp) | (1u << l) | (1u << tl);
471
111k
                }
472
1.01M
            }
473
1.18M
            const int color_idx = symbol_adapt(&ts->msac, color_map_cdf[ctx], pal_sz - 1);
474
1.18M
            pal_tmp[(i - j) * stride + j] =
475
1.18M
                resolve_pal_color(color_idx, p, prio_count, mask);
476
1.18M
        }
477
167k
    }
478
479
6.37k
    t->c->pal_dsp.pal_idx_finish(pal_idx, pal_tmp, bw4 * 4, bh4 * 4,
480
6.37k
                                 w4 * 4, h4 * 4);
481
6.37k
}
482
483
static void read_vartx_tree(Dav1dTaskContext *const t,
484
                            Av1Block *const b, const enum BlockSize bs,
485
                            const int bx4, const int by4)
486
565k
{
487
565k
    const Dav1dFrameContext *const f = t->f;
488
565k
    const uint8_t *const b_dim = dav1d_block_dimensions[bs];
489
565k
    const int bw4 = b_dim[0], bh4 = b_dim[1];
490
491
    // var-tx tree coding
492
565k
    uint16_t tx_split[2] = { 0 };
493
565k
    b->max_ytx = dav1d_max_txfm_size_for_bs[bs][0];
494
565k
    if (!b->skip && (f->frame_hdr->segmentation.lossless[b->seg_id] ||
495
156k
                     b->max_ytx == TX_4X4))
496
17.4k
    {
497
17.4k
        b->max_ytx = b->uvtx = TX_4X4;
498
17.4k
        if (f->frame_hdr->txfm_mode == DAV1D_TX_SWITCHABLE) {
499
6.61k
            dav1d_memset_pow2[b_dim[2]](&t->a->tx[bx4], TX_4X4);
500
6.61k
            dav1d_memset_pow2[b_dim[3]](&t->l.tx[by4], TX_4X4);
501
6.61k
        }
502
547k
    } else if (f->frame_hdr->txfm_mode != DAV1D_TX_SWITCHABLE || b->skip) {
503
470k
        if (f->frame_hdr->txfm_mode == DAV1D_TX_SWITCHABLE) {
504
143k
            dav1d_memset_pow2[b_dim[2]](&t->a->tx[bx4], b_dim[2 + 0]);
505
143k
            dav1d_memset_pow2[b_dim[3]](&t->l.tx[by4], b_dim[2 + 1]);
506
143k
        }
507
470k
        b->uvtx = dav1d_max_txfm_size_for_bs[bs][f->cur.p.layout];
508
470k
    } else {
509
77.1k
        assert(bw4 <= 16 || bh4 <= 16 || b->max_ytx == TX_64X64);
510
77.1k
        int y, x, y_off, x_off;
511
77.1k
        const TxfmInfo *const ytx = &dav1d_txfm_dimensions[b->max_ytx];
512
154k
        for (y = 0, y_off = 0; y < bh4; y += ytx->h, y_off++) {
513
156k
            for (x = 0, x_off = 0; x < bw4; x += ytx->w, x_off++) {
514
78.5k
                read_tx_tree(t, b->max_ytx, 0, tx_split, x_off, y_off);
515
                // contexts are updated inside read_tx_tree()
516
78.5k
                t->bx += ytx->w;
517
78.5k
            }
518
77.7k
            t->bx -= x;
519
77.7k
            t->by += ytx->h;
520
77.7k
        }
521
77.1k
        t->by -= y;
522
77.1k
        if (DEBUG_BLOCK_INFO)
523
0
            printf("Post-vartxtree[%x/%x]: r=%d\n",
524
0
                   tx_split[0], tx_split[1], t->ts->msac.rng);
525
77.1k
        b->uvtx = dav1d_max_txfm_size_for_bs[bs][f->cur.p.layout];
526
77.1k
    }
527
565k
    assert(!(tx_split[0] & ~0x33));
528
565k
    b->tx_split0 = (uint8_t)tx_split[0];
529
565k
    b->tx_split1 = tx_split[1];
530
565k
}
531
532
static inline unsigned get_prev_frame_segid(const Dav1dFrameContext *const f,
533
                                            const int by, const int bx,
534
                                            const int w4, int h4,
535
                                            const uint8_t *ref_seg_map,
536
                                            const ptrdiff_t stride)
537
31.4k
{
538
31.4k
    assert(f->frame_hdr->primary_ref_frame != DAV1D_PRIMARY_REF_NONE);
539
540
31.4k
    unsigned seg_id = 8;
541
31.4k
    ref_seg_map += by * stride + bx;
542
36.3k
    do {
543
175k
        for (int x = 0; x < w4; x++)
544
138k
            seg_id = imin(seg_id, ref_seg_map[x]);
545
36.3k
        ref_seg_map += stride;
546
36.3k
    } while (--h4 > 0 && seg_id);
547
31.4k
    assert(seg_id < 8);
548
549
31.4k
    return seg_id;
550
31.4k
}
551
552
static inline void splat_oneref_mv(const Dav1dContext *const c,
553
                                   Dav1dTaskContext *const t,
554
                                   const enum BlockSize bs,
555
                                   const Av1Block *const b,
556
                                   const int bw4, const int bh4)
557
228k
{
558
228k
    const enum InterPredMode mode = b->inter_mode;
559
228k
    const refmvs_block ALIGN(tmpl, 16) = (refmvs_block) {
560
228k
        .ref.ref = { b->ref[0] + 1, b->interintra_type ? 0 : -1 },
561
228k
        .mv.mv[0] = b->mv[0],
562
228k
        .bs = bs,
563
228k
        .mf = (mode == GLOBALMV && imin(bw4, bh4) >= 2) | ((mode == NEWMV) * 2),
564
228k
    };
565
228k
    c->refmvs_dsp.splat_mv(&t->rt.r[(t->by & 31) + 5], &tmpl, t->bx, bw4, bh4);
566
228k
}
567
568
static inline void splat_intrabc_mv(const Dav1dContext *const c,
569
                                    Dav1dTaskContext *const t,
570
                                    const enum BlockSize bs,
571
                                    const Av1Block *const b,
572
                                    const int bw4, const int bh4)
573
294k
{
574
294k
    const refmvs_block ALIGN(tmpl, 16) = (refmvs_block) {
575
294k
        .ref.ref = { 0, -1 },
576
294k
        .mv.mv[0] = b->mv[0],
577
294k
        .bs = bs,
578
294k
        .mf = 0,
579
294k
    };
580
294k
    c->refmvs_dsp.splat_mv(&t->rt.r[(t->by & 31) + 5], &tmpl, t->bx, bw4, bh4);
581
294k
}
582
583
static inline void splat_tworef_mv(const Dav1dContext *const c,
584
                                   Dav1dTaskContext *const t,
585
                                   const enum BlockSize bs,
586
                                   const Av1Block *const b,
587
                                   const int bw4, const int bh4)
588
42.7k
{
589
42.7k
    assert(bw4 >= 2 && bh4 >= 2);
590
42.7k
    const enum CompInterPredMode mode = b->inter_mode;
591
42.7k
    const refmvs_block ALIGN(tmpl, 16) = (refmvs_block) {
592
42.7k
        .ref.ref = { b->ref[0] + 1, b->ref[1] + 1 },
593
42.7k
        .mv.mv = { b->mv[0], b->mv[1] },
594
42.7k
        .bs = bs,
595
42.7k
        .mf = (mode == GLOBALMV_GLOBALMV) | !!((1 << mode) & (0xbc)) * 2,
596
42.7k
    };
597
42.7k
    c->refmvs_dsp.splat_mv(&t->rt.r[(t->by & 31) + 5], &tmpl, t->bx, bw4, bh4);
598
42.7k
}
599
600
static inline void splat_intraref(const Dav1dContext *const c,
601
                                  Dav1dTaskContext *const t,
602
                                  const enum BlockSize bs,
603
                                  const int bw4, const int bh4)
604
204k
{
605
204k
    const refmvs_block ALIGN(tmpl, 16) = (refmvs_block) {
606
204k
        .ref.ref = { 0, -1 },
607
204k
        .mv.mv[0].n = INVALID_MV,
608
204k
        .bs = bs,
609
204k
        .mf = 0,
610
204k
    };
611
204k
    c->refmvs_dsp.splat_mv(&t->rt.r[(t->by & 31) + 5], &tmpl, t->bx, bw4, bh4);
612
204k
}
613
614
static void mc_lowest_px(int *const dst, const int by4, const int bh4,
615
                         const int mvy, const int ss_ver,
616
                         const struct ScalableMotionParams *const smp)
617
523k
{
618
523k
    const int v_mul = 4 >> ss_ver;
619
523k
    if (!smp->scale) {
620
264k
        const int my = mvy >> (3 + ss_ver), dy = mvy & (15 >> !ss_ver);
621
264k
        *dst = imax(*dst, (by4 + bh4) * v_mul + my + 4 * !!dy);
622
264k
    } else {
623
259k
        int y = (by4 * v_mul << 4) + mvy * (1 << !ss_ver);
624
259k
        const int64_t tmp = (int64_t)(y) * smp->scale + (smp->scale - 0x4000) * 8;
625
259k
        y = apply_sign64((int)((llabs(tmp) + 128) >> 8), tmp) + 32;
626
259k
        const int bottom = ((y + (bh4 * v_mul - 1) * smp->step) >> 10) + 1 + 4;
627
259k
        *dst = imax(*dst, bottom);
628
259k
    }
629
523k
}
630
631
static ALWAYS_INLINE void affine_lowest_px(Dav1dTaskContext *const t, int *const dst,
632
                                           const uint8_t *const b_dim,
633
                                           const Dav1dWarpedMotionParams *const wmp,
634
                                           const int ss_ver, const int ss_hor)
635
18.9k
{
636
18.9k
    const int h_mul = 4 >> ss_hor, v_mul = 4 >> ss_ver;
637
18.9k
    assert(!((b_dim[0] * h_mul) & 7) && !((b_dim[1] * v_mul) & 7));
638
18.9k
    const int32_t *const mat = wmp->matrix;
639
18.9k
    const int y = b_dim[1] * v_mul - 8; // lowest y
640
641
18.9k
    const int src_y = t->by * 4 + ((y + 4) << ss_ver);
642
18.9k
    const int64_t mat5_y = (int64_t) mat[5] * src_y + mat[1];
643
    // check left- and right-most blocks
644
49.3k
    for (int x = 0; x < b_dim[0] * h_mul; x += imax(8, b_dim[0] * h_mul - 8)) {
645
        // calculate transformation relative to center of 8x8 block in
646
        // luma pixel units
647
30.3k
        const int src_x = t->bx * 4 + ((x + 4) << ss_hor);
648
30.3k
        const int64_t mvy = ((int64_t) mat[4] * src_x + mat5_y) >> ss_ver;
649
30.3k
        const int dy = (int) (mvy >> 16) - 4;
650
30.3k
        *dst = imax(*dst, dy + 4 + 8);
651
30.3k
    }
652
18.9k
}
653
654
static NOINLINE void affine_lowest_px_luma(Dav1dTaskContext *const t, int *const dst,
655
                                           const uint8_t *const b_dim,
656
                                           const Dav1dWarpedMotionParams *const wmp)
657
13.5k
{
658
13.5k
    affine_lowest_px(t, dst, b_dim, wmp, 0, 0);
659
13.5k
}
660
661
static NOINLINE void affine_lowest_px_chroma(Dav1dTaskContext *const t, int *const dst,
662
                                             const uint8_t *const b_dim,
663
                                             const Dav1dWarpedMotionParams *const wmp)
664
6.12k
{
665
6.12k
    const Dav1dFrameContext *const f = t->f;
666
6.12k
    assert(f->cur.p.layout != DAV1D_PIXEL_LAYOUT_I400);
667
6.12k
    if (f->cur.p.layout == DAV1D_PIXEL_LAYOUT_I444)
668
729
        affine_lowest_px_luma(t, dst, b_dim, wmp);
669
5.39k
    else
670
5.39k
        affine_lowest_px(t, dst, b_dim, wmp, f->cur.p.layout & DAV1D_PIXEL_LAYOUT_I420, 1);
671
6.12k
}
672
673
static void obmc_lowest_px(Dav1dTaskContext *const t,
674
                           int (*const dst)[2], const int is_chroma,
675
                           const uint8_t *const b_dim,
676
                           const int bx4, const int by4, const int w4, const int h4)
677
38.6k
{
678
38.6k
    assert(!(t->bx & 1) && !(t->by & 1));
679
38.6k
    const Dav1dFrameContext *const f = t->f;
680
38.6k
    /*const*/ refmvs_block **r = &t->rt.r[(t->by & 31) + 5];
681
38.6k
    const int ss_ver = is_chroma && f->cur.p.layout == DAV1D_PIXEL_LAYOUT_I420;
682
38.6k
    const int ss_hor = is_chroma && f->cur.p.layout != DAV1D_PIXEL_LAYOUT_I444;
683
38.6k
    const int h_mul = 4 >> ss_hor, v_mul = 4 >> ss_ver;
684
685
38.6k
    if (t->by > t->ts->tiling.row_start &&
686
25.5k
        (!is_chroma || b_dim[0] * h_mul + b_dim[1] * v_mul >= 16))
687
20.3k
    {
688
42.7k
        for (int i = 0, x = 0; x < w4 && i < imin(b_dim[2], 4); ) {
689
            // only odd blocks are considered for overlap handling, hence +1
690
22.3k
            const refmvs_block *const a_r = &r[-1][t->bx + x + 1];
691
22.3k
            const uint8_t *const a_b_dim = dav1d_block_dimensions[a_r->bs];
692
693
22.3k
            if (a_r->ref.ref[0] > 0) {
694
21.9k
                const int oh4 = imin(b_dim[1], 16) >> 1;
695
21.9k
                mc_lowest_px(&dst[a_r->ref.ref[0] - 1][is_chroma], t->by,
696
21.9k
                             (oh4 * 3 + 3) >> 2, a_r->mv.mv[0].y, ss_ver,
697
21.9k
                             &f->svc[a_r->ref.ref[0] - 1][1]);
698
21.9k
                i++;
699
21.9k
            }
700
22.3k
            x += imax(a_b_dim[0], 2);
701
22.3k
        }
702
20.3k
    }
703
704
38.6k
    if (t->bx > t->ts->tiling.col_start)
705
57.1k
        for (int i = 0, y = 0; y < h4 && i < imin(b_dim[3], 4); ) {
706
            // only odd blocks are considered for overlap handling, hence +1
707
29.3k
            const refmvs_block *const l_r = &r[y + 1][t->bx - 1];
708
29.3k
            const uint8_t *const l_b_dim = dav1d_block_dimensions[l_r->bs];
709
710
29.3k
            if (l_r->ref.ref[0] > 0) {
711
28.8k
                const int oh4 = iclip(l_b_dim[1], 2, b_dim[1]);
712
28.8k
                mc_lowest_px(&dst[l_r->ref.ref[0] - 1][is_chroma],
713
28.8k
                             t->by + y, oh4, l_r->mv.mv[0].y, ss_ver,
714
28.8k
                             &f->svc[l_r->ref.ref[0] - 1][1]);
715
28.8k
                i++;
716
28.8k
            }
717
29.3k
            y += imax(l_b_dim[1], 2);
718
29.3k
        }
719
38.6k
}
720
721
static int decode_b(Dav1dTaskContext *const t,
722
                    const enum BlockLevel bl,
723
                    const enum BlockSize bs,
724
                    const enum BlockPartition bp,
725
1.73M
                    const enum EdgeFlags intra_edge_flags) {
726
1.73M
    Dav1dTileState *const ts = t->ts;
727
1.73M
    const Dav1dFrameContext *const f = t->f;
728
1.73M
    Av1Block b_mem, *const b = t->frame_thread.pass ?
729
18.4E
        &f->frame_thread.b[t->by * f->b4_stride + t->bx] : &b_mem;
730
1.73M
    const uint8_t *const b_dim = dav1d_block_dimensions[bs];
731
1.73M
    const int bx4 = t->bx & 31, by4 = t->by & 31;
732
1.73M
    const int ss_ver = f->cur.p.layout == DAV1D_PIXEL_LAYOUT_I420;
733
1.73M
    const int ss_hor = f->cur.p.layout != DAV1D_PIXEL_LAYOUT_I444;
734
1.73M
    const int cbx4 = bx4 >> ss_hor, cby4 = by4 >> ss_ver;
735
1.73M
    const int bw4 = b_dim[0], bh4 = b_dim[1];
736
1.73M
    const int w4 = imin(bw4, f->bw - t->bx), h4 = imin(bh4, f->bh - t->by);
737
1.73M
    const int cbw4 = (bw4 + ss_hor) >> ss_hor, cbh4 = (bh4 + ss_ver) >> ss_ver;
738
1.73M
    const int have_left = t->bx > ts->tiling.col_start;
739
1.73M
    const int have_top = t->by > ts->tiling.row_start;
740
1.73M
    const int has_chroma = f->cur.p.layout != DAV1D_PIXEL_LAYOUT_I400 &&
741
1.30M
                           (bw4 > ss_hor || t->bx & 1) &&
742
1.11M
                           (bh4 > ss_ver || t->by & 1);
743
744
1.73M
    if (t->frame_thread.pass == 2) {
745
441k
        if (b->intra) {
746
304k
            f->bd_fn.recon_b_intra(t, bs, intra_edge_flags, b);
747
748
304k
            const enum IntraPredMode y_mode_nofilt =
749
304k
                b->y_mode == FILTER_PRED ? DC_PRED : b->y_mode;
750
304k
#define set_ctx(rep_macro) \
751
609k
            rep_macro(edge->mode, off, y_mode_nofilt); \
752
609k
            rep_macro(edge->intra, off, 1)
753
304k
            BlockContext *edge = t->a;
754
913k
            for (int i = 0, off = bx4; i < 2; i++, off = by4, edge = &t->l) {
755
608k
                case_set(b_dim[2 + i]);
756
608k
            }
757
304k
#undef set_ctx
758
304k
            if (IS_INTER_OR_SWITCH(f->frame_hdr)) {
759
7.08k
                refmvs_block *const r = &t->rt.r[(t->by & 31) + 5 + bh4 - 1][t->bx];
760
49.4k
                for (int x = 0; x < bw4; x++) {
761
42.3k
                    r[x].ref.ref[0] = 0;
762
42.3k
                    r[x].bs = bs;
763
42.3k
                }
764
7.08k
                refmvs_block *const *rr = &t->rt.r[(t->by & 31) + 5];
765
7.08k
                const int bx = t->bx + bw4 - 1;
766
35.7k
                for (int y = 0; y < bh4 - 1; y++) {
767
28.7k
                    refmvs_block *d = &rr[y][bx];
768
28.7k
                    d->ref.ref[0] = 0;
769
28.7k
                    d->bs = bs;
770
28.7k
                }
771
7.08k
            }
772
773
304k
            if (has_chroma) {
774
172k
                uint8_t uv_mode = b->uv_mode;
775
172k
                dav1d_memset_pow2[ulog2(cbw4)](&t->a->uvmode[cbx4], uv_mode);
776
172k
                dav1d_memset_pow2[ulog2(cbh4)](&t->l.uvmode[cby4], uv_mode);
777
172k
            }
778
304k
        } else {
779
137k
            if (IS_INTER_OR_SWITCH(f->frame_hdr) /* not intrabc */ &&
780
107k
                b->comp_type == COMP_INTER_NONE && b->motion_mode == MM_WARP)
781
1.29k
            {
782
1.29k
                if (b->matrix[0] == INT16_MIN) {
783
197
                    t->warpmv.type = DAV1D_WM_TYPE_IDENTITY;
784
1.10k
                } else {
785
1.10k
                    t->warpmv.type = DAV1D_WM_TYPE_AFFINE;
786
1.10k
                    t->warpmv.matrix[2] = b->matrix[0] + 0x10000;
787
1.10k
                    t->warpmv.matrix[3] = b->matrix[1];
788
1.10k
                    t->warpmv.matrix[4] = b->matrix[2];
789
1.10k
                    t->warpmv.matrix[5] = b->matrix[3] + 0x10000;
790
1.10k
                    dav1d_set_affine_mv2d(bw4, bh4, b->mv2d, &t->warpmv,
791
1.10k
                                          t->bx, t->by);
792
1.10k
                    dav1d_get_shear_params(&t->warpmv);
793
1.10k
#define signabs(v) v < 0 ? '-' : ' ', abs(v)
794
1.10k
                    if (DEBUG_BLOCK_INFO)
795
0
                        printf("[ %c%x %c%x %c%x\n  %c%x %c%x %c%x ]\n"
796
0
                               "alpha=%c%x, beta=%c%x, gamma=%c%x, delta=%c%x, mv=y:%d,x:%d\n",
797
0
                               signabs(t->warpmv.matrix[0]),
798
0
                               signabs(t->warpmv.matrix[1]),
799
0
                               signabs(t->warpmv.matrix[2]),
800
0
                               signabs(t->warpmv.matrix[3]),
801
0
                               signabs(t->warpmv.matrix[4]),
802
0
                               signabs(t->warpmv.matrix[5]),
803
0
                               signabs(t->warpmv.u.p.alpha),
804
0
                               signabs(t->warpmv.u.p.beta),
805
0
                               signabs(t->warpmv.u.p.gamma),
806
0
                               signabs(t->warpmv.u.p.delta),
807
0
                               b->mv2d.y, b->mv2d.x);
808
1.10k
#undef signabs
809
1.10k
                }
810
1.29k
            }
811
137k
            if (f->bd_fn.recon_b_inter(t, bs, b)) return -1;
812
813
137k
            const uint8_t *const filter = dav1d_filter_dir[b->filter2d];
814
137k
            BlockContext *edge = t->a;
815
411k
            for (int i = 0, off = bx4; i < 2; i++, off = by4, edge = &t->l) {
816
274k
#define set_ctx(rep_macro) \
817
274k
                rep_macro(edge->filter[0], off, filter[0]); \
818
274k
                rep_macro(edge->filter[1], off, filter[1]); \
819
274k
                rep_macro(edge->intra, off, 0)
820
274k
                case_set(b_dim[2 + i]);
821
274k
#undef set_ctx
822
274k
            }
823
824
137k
            if (IS_INTER_OR_SWITCH(f->frame_hdr)) {
825
107k
                refmvs_block *const r = &t->rt.r[(t->by & 31) + 5 + bh4 - 1][t->bx];
826
107k
                const int ref1 = b->ref[0] + 1;
827
107k
                const union mv mv1 = b->mv[0];
828
533k
                for (int x = 0; x < bw4; x++) {
829
425k
                    r[x].ref.ref[0] = ref1;
830
425k
                    r[x].mv.mv[0] = mv1;
831
425k
                    r[x].bs = bs;
832
425k
                }
833
107k
                refmvs_block *const *rr = &t->rt.r[(t->by & 31) + 5];
834
107k
                const int bx = t->bx + bw4 - 1;
835
496k
                for (int y = 0; y < bh4 - 1; y++) {
836
389k
                    refmvs_block* d = &rr[y][bx];
837
389k
                    d->ref.ref[0] = ref1;
838
389k
                    d->mv.mv[0] = mv1;
839
389k
                    d->bs = bs;
840
389k
                }
841
107k
            }
842
843
137k
            if (has_chroma) {
844
62.5k
                dav1d_memset_pow2[ulog2(cbw4)](&t->a->uvmode[cbx4], DC_PRED);
845
62.5k
                dav1d_memset_pow2[ulog2(cbh4)](&t->l.uvmode[cby4], DC_PRED);
846
62.5k
            }
847
137k
        }
848
441k
        return 0;
849
441k
    }
850
851
1.29M
    const int cw4 = (w4 + ss_hor) >> ss_hor, ch4 = (h4 + ss_ver) >> ss_ver;
852
853
1.29M
    b->bl = bl;
854
1.29M
    b->bp = bp;
855
1.29M
    b->bs = bs;
856
857
1.29M
    const Dav1dSegmentationData *seg = NULL;
858
859
    // segment_id (if seg_feature for skip/ref/gmv is enabled)
860
1.29M
    int seg_pred = 0;
861
1.29M
    if (f->frame_hdr->segmentation.enabled) {
862
609k
        if (!f->frame_hdr->segmentation.update_map) {
863
38.5k
            if (f->prev_segmap) {
864
29.3k
                unsigned seg_id = get_prev_frame_segid(f, t->by, t->bx, w4, h4,
865
29.3k
                                                       f->prev_segmap,
866
29.3k
                                                       f->b4_stride);
867
29.3k
                if (seg_id >= 8) return -1;
868
29.3k
                b->seg_id = seg_id;
869
29.3k
            } else {
870
9.20k
                b->seg_id = 0;
871
9.20k
            }
872
38.5k
            seg = &f->frame_hdr->segmentation.seg_data.d[b->seg_id];
873
570k
        } else if (f->frame_hdr->segmentation.seg_data.preskip) {
874
483k
            if (f->frame_hdr->segmentation.temporal &&
875
6.04k
                (seg_pred = dav1d_msac_decode_bool_adapt(&ts->msac,
876
6.04k
                                ts->cdf.m.seg_pred[t->a->seg_pred[bx4] +
877
6.04k
                                t->l.seg_pred[by4]])))
878
2.93k
            {
879
                // temporal predicted seg_id
880
2.93k
                if (f->prev_segmap) {
881
1.88k
                    unsigned seg_id = get_prev_frame_segid(f, t->by, t->bx,
882
1.88k
                                                           w4, h4,
883
1.88k
                                                           f->prev_segmap,
884
1.88k
                                                           f->b4_stride);
885
1.88k
                    if (seg_id >= 8) return -1;
886
1.88k
                    b->seg_id = seg_id;
887
1.88k
                } else {
888
1.05k
                    b->seg_id = 0;
889
1.05k
                }
890
480k
            } else {
891
480k
                int seg_ctx;
892
480k
                const unsigned pred_seg_id =
893
480k
                    get_cur_frame_segid(t->by, t->bx, have_top, have_left,
894
480k
                                        &seg_ctx, f->cur_segmap, f->b4_stride);
895
480k
                const unsigned diff = dav1d_msac_decode_symbol_adapt8(&ts->msac,
896
480k
                                          ts->cdf.m.seg_id[seg_ctx],
897
480k
                                          DAV1D_MAX_SEGMENTS - 1);
898
480k
                const unsigned last_active_seg_id =
899
480k
                    f->frame_hdr->segmentation.seg_data.last_active_segid;
900
480k
                b->seg_id = neg_deinterleave(diff, pred_seg_id,
901
480k
                                             last_active_seg_id + 1);
902
480k
                if (b->seg_id > last_active_seg_id) b->seg_id = 0; // error?
903
480k
                if (b->seg_id >= DAV1D_MAX_SEGMENTS) b->seg_id = 0; // error?
904
480k
            }
905
906
483k
            if (DEBUG_BLOCK_INFO)
907
0
                printf("Post-segid[preskip;%d]: r=%d\n",
908
0
                       b->seg_id, ts->msac.rng);
909
910
483k
            seg = &f->frame_hdr->segmentation.seg_data.d[b->seg_id];
911
483k
        }
912
685k
    } else {
913
685k
        b->seg_id = 0;
914
685k
    }
915
916
    // skip_mode
917
1.29M
    if ((!seg || (!seg->globalmv && seg->ref == -1 && !seg->skip)) &&
918
987k
        f->frame_hdr->skip_mode_enabled && imin(bw4, bh4) > 1)
919
2.08k
    {
920
2.08k
        const int smctx = t->a->skip_mode[bx4] + t->l.skip_mode[by4];
921
2.08k
        b->skip_mode = dav1d_msac_decode_bool_adapt(&ts->msac,
922
2.08k
                           ts->cdf.m.skip_mode[smctx]);
923
2.08k
        if (DEBUG_BLOCK_INFO)
924
0
            printf("Post-skipmode[%d]: r=%d\n", b->skip_mode, ts->msac.rng);
925
1.29M
    } else {
926
1.29M
        b->skip_mode = 0;
927
1.29M
    }
928
929
    // skip
930
1.29M
    if (b->skip_mode || (seg && seg->skip)) {
931
236k
        b->skip = 1;
932
1.05M
    } else {
933
1.05M
        const int sctx = t->a->skip[bx4] + t->l.skip[by4];
934
1.05M
        b->skip = dav1d_msac_decode_bool_adapt(&ts->msac, ts->cdf.m.skip[sctx]);
935
1.05M
        if (DEBUG_BLOCK_INFO)
936
0
            printf("Post-skip[%d]: r=%d\n", b->skip, ts->msac.rng);
937
1.05M
    }
938
939
    // segment_id
940
1.29M
    if (f->frame_hdr->segmentation.enabled &&
941
610k
        f->frame_hdr->segmentation.update_map &&
942
571k
        !f->frame_hdr->segmentation.seg_data.preskip)
943
87.0k
    {
944
87.0k
        if (!b->skip && f->frame_hdr->segmentation.temporal &&
945
1.81k
            (seg_pred = dav1d_msac_decode_bool_adapt(&ts->msac,
946
1.81k
                            ts->cdf.m.seg_pred[t->a->seg_pred[bx4] +
947
1.81k
                            t->l.seg_pred[by4]])))
948
877
        {
949
            // temporal predicted seg_id
950
877
            if (f->prev_segmap) {
951
213
                unsigned seg_id = get_prev_frame_segid(f, t->by, t->bx, w4, h4,
952
213
                                                       f->prev_segmap,
953
213
                                                       f->b4_stride);
954
213
                if (seg_id >= 8) return -1;
955
213
                b->seg_id = seg_id;
956
664
            } else {
957
664
                b->seg_id = 0;
958
664
            }
959
86.1k
        } else {
960
86.1k
            int seg_ctx;
961
86.1k
            const unsigned pred_seg_id =
962
86.1k
                get_cur_frame_segid(t->by, t->bx, have_top, have_left,
963
86.1k
                                    &seg_ctx, f->cur_segmap, f->b4_stride);
964
86.1k
            if (b->skip) {
965
59.0k
                b->seg_id = pred_seg_id;
966
59.0k
            } else {
967
27.1k
                const unsigned diff = dav1d_msac_decode_symbol_adapt8(&ts->msac,
968
27.1k
                                          ts->cdf.m.seg_id[seg_ctx],
969
27.1k
                                          DAV1D_MAX_SEGMENTS - 1);
970
27.1k
                const unsigned last_active_seg_id =
971
27.1k
                    f->frame_hdr->segmentation.seg_data.last_active_segid;
972
27.1k
                b->seg_id = neg_deinterleave(diff, pred_seg_id,
973
27.1k
                                             last_active_seg_id + 1);
974
27.1k
                if (b->seg_id > last_active_seg_id) b->seg_id = 0; // error?
975
27.1k
            }
976
86.1k
            if (b->seg_id >= DAV1D_MAX_SEGMENTS) b->seg_id = 0; // error?
977
86.1k
        }
978
979
87.0k
        seg = &f->frame_hdr->segmentation.seg_data.d[b->seg_id];
980
981
87.0k
        if (DEBUG_BLOCK_INFO)
982
0
            printf("Post-segid[postskip;%d]: r=%d\n",
983
0
                   b->seg_id, ts->msac.rng);
984
87.0k
    }
985
986
    // cdef index
987
1.29M
    if (!b->skip) {
988
486k
        const int idx = f->seq_hdr->sb128 ? ((t->bx & 16) >> 4) +
989
359k
                                           ((t->by & 16) >> 3) : 0;
990
486k
        if (t->cur_sb_cdef_idx_ptr[idx] == -1) {
991
155k
            const int v = dav1d_msac_decode_bools(&ts->msac,
992
155k
                              f->frame_hdr->cdef.n_bits);
993
155k
            t->cur_sb_cdef_idx_ptr[idx] = v;
994
155k
            if (bw4 > 16) t->cur_sb_cdef_idx_ptr[idx + 1] = v;
995
155k
            if (bh4 > 16) t->cur_sb_cdef_idx_ptr[idx + 2] = v;
996
155k
            if (bw4 == 32 && bh4 == 32) t->cur_sb_cdef_idx_ptr[idx + 3] = v;
997
998
155k
            if (DEBUG_BLOCK_INFO)
999
0
                printf("Post-cdef_idx[%d]: r=%d\n",
1000
0
                        *t->cur_sb_cdef_idx_ptr, ts->msac.rng);
1001
155k
        }
1002
486k
    }
1003
1004
    // delta-q/lf
1005
1.29M
    if (!((t->bx | t->by) & (31 >> !f->seq_hdr->sb128))) {
1006
215k
        const int prev_qidx = ts->last_qidx;
1007
215k
        const int have_delta_q = f->frame_hdr->delta.q.present &&
1008
67.0k
            (bs != (f->seq_hdr->sb128 ? BS_128x128 : BS_64x64) || !b->skip);
1009
1010
215k
        uint32_t prev_delta_lf = ts->last_delta_lf.u32;
1011
1012
215k
        if (have_delta_q) {
1013
66.5k
            int delta_q = dav1d_msac_decode_symbol_adapt4(&ts->msac,
1014
66.5k
                                                          ts->cdf.m.delta_q, 3);
1015
66.5k
            if (delta_q == 3) {
1016
6.33k
                const int n_bits = 1 + dav1d_msac_decode_bools(&ts->msac, 3);
1017
6.33k
                delta_q = dav1d_msac_decode_bools(&ts->msac, n_bits) +
1018
6.33k
                          1 + (1 << n_bits);
1019
6.33k
            }
1020
66.5k
            if (delta_q) {
1021
14.2k
                if (dav1d_msac_decode_bool_equi(&ts->msac)) delta_q = -delta_q;
1022
14.2k
                delta_q *= 1 << f->frame_hdr->delta.q.res_log2;
1023
14.2k
            }
1024
66.5k
            ts->last_qidx = iclip(ts->last_qidx + delta_q, 1, 255);
1025
66.5k
            if (have_delta_q && DEBUG_BLOCK_INFO)
1026
0
                printf("Post-delta_q[%d->%d]: r=%d\n",
1027
0
                       delta_q, ts->last_qidx, ts->msac.rng);
1028
1029
66.5k
            if (f->frame_hdr->delta.lf.present) {
1030
30.6k
                const int n_lfs = f->frame_hdr->delta.lf.multi ?
1031
23.9k
                    f->cur.p.layout != DAV1D_PIXEL_LAYOUT_I400 ? 4 : 2 : 1;
1032
1033
123k
                for (int i = 0; i < n_lfs; i++) {
1034
92.4k
                    int delta_lf = dav1d_msac_decode_symbol_adapt4(&ts->msac,
1035
92.4k
                        ts->cdf.m.delta_lf[i + f->frame_hdr->delta.lf.multi], 3);
1036
92.4k
                    if (delta_lf == 3) {
1037
9.74k
                        const int n_bits = 1 + dav1d_msac_decode_bools(&ts->msac, 3);
1038
9.74k
                        delta_lf = dav1d_msac_decode_bools(&ts->msac, n_bits) +
1039
9.74k
                                   1 + (1 << n_bits);
1040
9.74k
                    }
1041
92.4k
                    if (delta_lf) {
1042
20.2k
                        if (dav1d_msac_decode_bool_equi(&ts->msac))
1043
14.7k
                            delta_lf = -delta_lf;
1044
20.2k
                        delta_lf *= 1 << f->frame_hdr->delta.lf.res_log2;
1045
20.2k
                    }
1046
92.4k
                    ts->last_delta_lf.i8[i] =
1047
92.4k
                        iclip(ts->last_delta_lf.i8[i] + delta_lf, -63, 63);
1048
92.4k
                    if (have_delta_q && DEBUG_BLOCK_INFO)
1049
0
                        printf("Post-delta_lf[%d:%d]: r=%d\n", i, delta_lf,
1050
0
                               ts->msac.rng);
1051
92.4k
                }
1052
30.6k
            }
1053
66.5k
        }
1054
215k
        if (ts->last_qidx == f->frame_hdr->quant.yac) {
1055
            // assign frame-wide q values to this sb
1056
177k
            ts->dq = f->dq;
1057
177k
        } else if (ts->last_qidx != prev_qidx) {
1058
            // find sb-specific quant parameters
1059
7.72k
            init_quant_tables(f->seq_hdr, f->frame_hdr, ts->last_qidx, ts->dqmem);
1060
7.72k
            ts->dq = ts->dqmem;
1061
7.72k
        }
1062
215k
        if (!ts->last_delta_lf.u32) {
1063
            // assign frame-wide lf values to this sb
1064
191k
            ts->lflvl = f->lf.lvl;
1065
191k
        } else if (ts->last_delta_lf.u32 != prev_delta_lf) {
1066
            // find sb-specific lf lvl parameters
1067
9.05k
            ts->lflvl = ts->lflvlmem;
1068
9.05k
            dav1d_calc_lf_values(ts->lflvlmem, f->frame_hdr, ts->last_delta_lf.i8);
1069
9.05k
        }
1070
215k
    }
1071
1072
1.29M
    if (b->skip_mode) {
1073
551
        b->intra = 0;
1074
1.29M
    } else if (IS_INTER_OR_SWITCH(f->frame_hdr)) {
1075
294k
        if (seg && (seg->ref >= 0 || seg->globalmv)) {
1076
55.3k
            b->intra = !seg->ref;
1077
239k
        } else {
1078
239k
            const int ictx = get_intra_ctx(t->a, &t->l, by4, bx4,
1079
239k
                                           have_top, have_left);
1080
239k
            b->intra = !dav1d_msac_decode_bool_adapt(&ts->msac,
1081
239k
                            ts->cdf.m.intra[ictx]);
1082
239k
            if (DEBUG_BLOCK_INFO)
1083
0
                printf("Post-intra[%d]: r=%d\n", b->intra, ts->msac.rng);
1084
239k
        }
1085
999k
    } else if (f->frame_hdr->allow_intrabc) {
1086
473k
        b->intra = !dav1d_msac_decode_bool_adapt(&ts->msac, ts->cdf.m.intrabc);
1087
473k
        if (DEBUG_BLOCK_INFO)
1088
0
            printf("Post-intrabcflag[%d]: r=%d\n", b->intra, ts->msac.rng);
1089
526k
    } else {
1090
526k
        b->intra = 1;
1091
526k
    }
1092
1093
    // intra/inter-specific stuff
1094
1.29M
    if (b->intra) {
1095
730k
        uint16_t *const ymode_cdf = IS_INTER_OR_SWITCH(f->frame_hdr) ?
1096
24.4k
            ts->cdf.m.y_mode[dav1d_ymode_size_context[bs]] :
1097
730k
            ts->cdf.kfym[dav1d_intra_mode_context[t->a->mode[bx4]]]
1098
706k
                        [dav1d_intra_mode_context[t->l.mode[by4]]];
1099
730k
        b->y_mode = dav1d_msac_decode_symbol_adapt16(&ts->msac, ymode_cdf,
1100
730k
                                                     N_INTRA_PRED_MODES - 1);
1101
730k
        if (DEBUG_BLOCK_INFO)
1102
0
            printf("Post-ymode[%d]: r=%d\n", b->y_mode, ts->msac.rng);
1103
1104
        // angle delta
1105
730k
        if (b_dim[2] + b_dim[3] >= 2 && b->y_mode >= VERT_PRED &&
1106
209k
            b->y_mode <= VERT_LEFT_PRED)
1107
111k
        {
1108
111k
            uint16_t *const acdf = ts->cdf.m.angle_delta[b->y_mode - VERT_PRED];
1109
111k
            const int angle = dav1d_msac_decode_symbol_adapt8(&ts->msac, acdf, 6);
1110
111k
            b->y_angle = angle - 3;
1111
619k
        } else {
1112
619k
            b->y_angle = 0;
1113
619k
        }
1114
1115
730k
        if (has_chroma) {
1116
422k
            const int cfl_allowed = f->frame_hdr->segmentation.lossless[b->seg_id] ?
1117
402k
                cbw4 == 1 && cbh4 == 1 : !!(cfl_allowed_mask & (1 << bs));
1118
422k
            uint16_t *const uvmode_cdf = ts->cdf.m.uv_mode[cfl_allowed][b->y_mode];
1119
422k
            b->uv_mode = dav1d_msac_decode_symbol_adapt16(&ts->msac, uvmode_cdf,
1120
422k
                             N_UV_INTRA_PRED_MODES - 1 - !cfl_allowed);
1121
422k
            if (DEBUG_BLOCK_INFO)
1122
0
                printf("Post-uvmode[%d]: r=%d\n", b->uv_mode, ts->msac.rng);
1123
1124
422k
            b->uv_angle = 0;
1125
422k
            if (b->uv_mode == CFL_PRED) {
1126
140k
#define SIGN(a) (!!(a) + ((a) > 0))
1127
140k
                const int sign = dav1d_msac_decode_symbol_adapt8(&ts->msac,
1128
140k
                                     ts->cdf.m.cfl_sign, 7) + 1;
1129
140k
                const int sign_u = sign * 0x56 >> 8, sign_v = sign - sign_u * 3;
1130
140k
                assert(sign_u == sign / 3);
1131
140k
                if (sign_u) {
1132
136k
                    const int ctx = (sign_u == 2) * 3 + sign_v;
1133
136k
                    b->cfl_alpha[0] = dav1d_msac_decode_symbol_adapt16(&ts->msac,
1134
136k
                                          ts->cdf.m.cfl_alpha[ctx], 15) + 1;
1135
136k
                    if (sign_u == 1) b->cfl_alpha[0] = -b->cfl_alpha[0];
1136
136k
                } else {
1137
4.31k
                    b->cfl_alpha[0] = 0;
1138
4.31k
                }
1139
140k
                if (sign_v) {
1140
116k
                    const int ctx = (sign_v == 2) * 3 + sign_u;
1141
116k
                    b->cfl_alpha[1] = dav1d_msac_decode_symbol_adapt16(&ts->msac,
1142
116k
                                          ts->cdf.m.cfl_alpha[ctx], 15) + 1;
1143
116k
                    if (sign_v == 1) b->cfl_alpha[1] = -b->cfl_alpha[1];
1144
116k
                } else {
1145
24.1k
                    b->cfl_alpha[1] = 0;
1146
24.1k
                }
1147
140k
#undef SIGN
1148
140k
                if (DEBUG_BLOCK_INFO)
1149
0
                    printf("Post-uvalphas[%d/%d]: r=%d\n",
1150
0
                           b->cfl_alpha[0], b->cfl_alpha[1], ts->msac.rng);
1151
282k
            } else if (b_dim[2] + b_dim[3] >= 2 && b->uv_mode >= VERT_PRED &&
1152
135k
                       b->uv_mode <= VERT_LEFT_PRED)
1153
70.9k
            {
1154
70.9k
                uint16_t *const acdf = ts->cdf.m.angle_delta[b->uv_mode - VERT_PRED];
1155
70.9k
                const int angle = dav1d_msac_decode_symbol_adapt8(&ts->msac, acdf, 6);
1156
70.9k
                b->uv_angle = angle - 3;
1157
70.9k
            }
1158
422k
        }
1159
1160
730k
        b->pal_sz[0] = b->pal_sz[1] = 0;
1161
730k
        if (f->frame_hdr->allow_screen_content_tools &&
1162
325k
            imax(bw4, bh4) <= 16 && bw4 + bh4 >= 4)
1163
211k
        {
1164
211k
            const int sz_ctx = b_dim[2] + b_dim[3] - 2;
1165
211k
            if (b->y_mode == DC_PRED) {
1166
104k
                const int pal_ctx = (t->a->pal_sz[bx4] > 0) + (t->l.pal_sz[by4] > 0);
1167
104k
                const int use_y_pal = dav1d_msac_decode_bool_adapt(&ts->msac,
1168
104k
                                          ts->cdf.m.pal_y[sz_ctx][pal_ctx]);
1169
104k
                if (DEBUG_BLOCK_INFO)
1170
0
                    printf("Post-y_pal[%d]: r=%d\n", use_y_pal, ts->msac.rng);
1171
104k
                if (use_y_pal)
1172
6.43k
                    f->bd_fn.read_pal_plane(t, b, 0, sz_ctx, bx4, by4);
1173
104k
            }
1174
1175
211k
            if (has_chroma && b->uv_mode == DC_PRED) {
1176
49.5k
                const int pal_ctx = b->pal_sz[0] > 0;
1177
49.5k
                const int use_uv_pal = dav1d_msac_decode_bool_adapt(&ts->msac,
1178
49.5k
                                           ts->cdf.m.pal_uv[pal_ctx]);
1179
49.5k
                if (DEBUG_BLOCK_INFO)
1180
0
                    printf("Post-uv_pal[%d]: r=%d\n", use_uv_pal, ts->msac.rng);
1181
49.5k
                if (use_uv_pal) // see aomedia bug 2183 for why we use luma coordinates
1182
1.88k
                    f->bd_fn.read_pal_uv(t, b, sz_ctx, bx4, by4);
1183
49.5k
            }
1184
211k
        }
1185
1186
730k
        if (b->y_mode == DC_PRED && !b->pal_sz[0] &&
1187
239k
            imax(b_dim[2], b_dim[3]) <= 3 && f->seq_hdr->filter_intra)
1188
66.4k
        {
1189
66.4k
            const int is_filter = dav1d_msac_decode_bool_adapt(&ts->msac,
1190
66.4k
                                      ts->cdf.m.use_filter_intra[bs]);
1191
66.4k
            if (is_filter) {
1192
44.8k
                b->y_mode = FILTER_PRED;
1193
44.8k
                b->y_angle = dav1d_msac_decode_symbol_adapt8(&ts->msac,
1194
44.8k
                                 ts->cdf.m.filter_intra, 4);
1195
44.8k
            }
1196
66.4k
            if (DEBUG_BLOCK_INFO)
1197
0
                printf("Post-filterintramode[%d/%d]: r=%d\n",
1198
0
                       b->y_mode, b->y_angle, ts->msac.rng);
1199
66.4k
        }
1200
1201
730k
        if (b->pal_sz[0]) {
1202
6.43k
            uint8_t *pal_idx;
1203
6.43k
            if (t->frame_thread.pass) {
1204
6.43k
                const int p = t->frame_thread.pass & 1;
1205
6.43k
                assert(ts->frame_thread[p].pal_idx);
1206
6.43k
                pal_idx = ts->frame_thread[p].pal_idx;
1207
6.43k
                ts->frame_thread[p].pal_idx += bw4 * bh4 * 8;
1208
6.43k
            } else
1209
0
                pal_idx = t->scratch.pal_idx_y;
1210
6.43k
            read_pal_indices(t, pal_idx, b->pal_sz[0], 0, w4, h4, bw4, bh4);
1211
6.43k
            if (DEBUG_BLOCK_INFO)
1212
0
                printf("Post-y-pal-indices: r=%d\n", ts->msac.rng);
1213
6.43k
        }
1214
1215
730k
        if (has_chroma && b->pal_sz[1]) {
1216
1.88k
            uint8_t *pal_idx;
1217
1.88k
            if (t->frame_thread.pass) {
1218
1.88k
                const int p = t->frame_thread.pass & 1;
1219
1.88k
                assert(ts->frame_thread[p].pal_idx);
1220
1.88k
                pal_idx = ts->frame_thread[p].pal_idx;
1221
1.88k
                ts->frame_thread[p].pal_idx += cbw4 * cbh4 * 8;
1222
1.88k
            } else
1223
0
                pal_idx = t->scratch.pal_idx_uv;
1224
1.88k
            read_pal_indices(t, pal_idx, b->pal_sz[1], 1, cw4, ch4, cbw4, cbh4);
1225
1.88k
            if (DEBUG_BLOCK_INFO)
1226
0
                printf("Post-uv-pal-indices: r=%d\n", ts->msac.rng);
1227
1.88k
        }
1228
1229
730k
        const TxfmInfo *t_dim;
1230
730k
        if (f->frame_hdr->segmentation.lossless[b->seg_id]) {
1231
36.9k
            b->tx = b->uvtx = (int) TX_4X4;
1232
36.9k
            t_dim = &dav1d_txfm_dimensions[TX_4X4];
1233
693k
        } else {
1234
693k
            b->tx = dav1d_max_txfm_size_for_bs[bs][0];
1235
693k
            b->uvtx = dav1d_max_txfm_size_for_bs[bs][f->cur.p.layout];
1236
693k
            t_dim = &dav1d_txfm_dimensions[b->tx];
1237
693k
            if (f->frame_hdr->txfm_mode == DAV1D_TX_SWITCHABLE && t_dim->max > TX_4X4) {
1238
142k
                const int tctx = get_tx_ctx(t->a, &t->l, t_dim, by4, bx4);
1239
142k
                uint16_t *const tx_cdf = ts->cdf.m.txsz[t_dim->max - 1][tctx];
1240
142k
                int depth = dav1d_msac_decode_symbol_adapt4(&ts->msac, tx_cdf,
1241
142k
                                imin(t_dim->max, 2));
1242
1243
256k
                while (depth--) {
1244
113k
                    b->tx = t_dim->sub;
1245
113k
                    t_dim = &dav1d_txfm_dimensions[b->tx];
1246
113k
                }
1247
142k
            }
1248
693k
            if (DEBUG_BLOCK_INFO)
1249
0
                printf("Post-tx[%d]: r=%d\n", b->tx, ts->msac.rng);
1250
693k
        }
1251
1252
        // reconstruction
1253
731k
        if (t->frame_thread.pass == 1) {
1254
731k
            f->bd_fn.read_coef_blocks(t, bs, b);
1255
18.4E
        } else {
1256
18.4E
            f->bd_fn.recon_b_intra(t, bs, intra_edge_flags, b);
1257
18.4E
        }
1258
1259
730k
        if (f->frame_hdr->loopfilter.level_y[0] ||
1260
377k
            f->frame_hdr->loopfilter.level_y[1])
1261
415k
        {
1262
415k
            dav1d_create_lf_mask_intra(t->lf_mask, f->lf.level, f->b4_stride,
1263
415k
                                       (const uint8_t (*)[8][2])
1264
415k
                                       &ts->lflvl[b->seg_id][0][0][0],
1265
415k
                                       t->bx, t->by, f->w4, f->h4, bs,
1266
415k
                                       b->tx, b->uvtx, f->cur.p.layout,
1267
415k
                                       &t->a->tx_lpf_y[bx4], &t->l.tx_lpf_y[by4],
1268
415k
                                       has_chroma ? &t->a->tx_lpf_uv[cbx4] : NULL,
1269
415k
                                       has_chroma ? &t->l.tx_lpf_uv[cby4] : NULL);
1270
415k
        }
1271
        // update contexts
1272
730k
        const enum IntraPredMode y_mode_nofilt =
1273
730k
            b->y_mode == FILTER_PRED ? DC_PRED : b->y_mode;
1274
730k
        BlockContext *edge = t->a;
1275
2.19M
        for (int i = 0, off = bx4; i < 2; i++, off = by4, edge = &t->l) {
1276
1.46M
            int t_lsz = ((uint8_t *) &t_dim->lw)[i]; // lw then lh
1277
1.46M
#define set_ctx(rep_macro) \
1278
1.46M
            rep_macro(edge->tx_intra, off, t_lsz); \
1279
1.46M
            rep_macro(edge->tx, off, t_lsz); \
1280
1.46M
            rep_macro(edge->mode, off, y_mode_nofilt); \
1281
1.46M
            rep_macro(edge->pal_sz, off, b->pal_sz[0]); \
1282
1.46M
            rep_macro(edge->seg_pred, off, seg_pred); \
1283
1.46M
            rep_macro(edge->skip_mode, off, 0); \
1284
1.46M
            rep_macro(edge->intra, off, 1); \
1285
1.46M
            rep_macro(edge->skip, off, b->skip); \
1286
            /* see aomedia bug 2183 for why we use luma coordinates here */ \
1287
1.46M
            rep_macro(t->pal_sz_uv[i], off, (has_chroma ? b->pal_sz[1] : 0)); \
1288
1.46M
            if (IS_INTER_OR_SWITCH(f->frame_hdr)) { \
1289
48.8k
                rep_macro(edge->comp_type, off, COMP_INTER_NONE); \
1290
48.8k
                rep_macro(edge->ref[0], off, ((uint8_t) -1)); \
1291
48.8k
                rep_macro(edge->ref[1], off, ((uint8_t) -1)); \
1292
48.8k
                rep_macro(edge->filter[0], off, DAV1D_N_SWITCHABLE_FILTERS); \
1293
48.8k
                rep_macro(edge->filter[1], off, DAV1D_N_SWITCHABLE_FILTERS); \
1294
48.8k
            }
1295
1.46M
            case_set(b_dim[2 + i]);
1296
1.46M
#undef set_ctx
1297
1.46M
        }
1298
730k
        if (b->pal_sz[0])
1299
6.43k
            f->bd_fn.copy_pal_block_y(t, bx4, by4, bw4, bh4);
1300
730k
        if (has_chroma) {
1301
422k
            uint8_t uv_mode = b->uv_mode;
1302
422k
            dav1d_memset_pow2[ulog2(cbw4)](&t->a->uvmode[cbx4], uv_mode);
1303
422k
            dav1d_memset_pow2[ulog2(cbh4)](&t->l.uvmode[cby4], uv_mode);
1304
422k
            if (b->pal_sz[1])
1305
1.88k
                f->bd_fn.copy_pal_block_uv(t, bx4, by4, bw4, bh4);
1306
422k
        }
1307
730k
        if (IS_INTER_OR_SWITCH(f->frame_hdr) || f->frame_hdr->allow_intrabc)
1308
204k
            splat_intraref(f->c, t, bs, bw4, bh4);
1309
730k
    } else if (IS_KEY_OR_INTRA(f->frame_hdr)) {
1310
        // intra block copy
1311
293k
        refmvs_candidate mvstack[8];
1312
293k
        int n_mvs, ctx;
1313
293k
        dav1d_refmvs_find(&t->rt, mvstack, &n_mvs, &ctx,
1314
293k
                          (union refmvs_refpair) { .ref = { 0, -1 }},
1315
293k
                          bs, intra_edge_flags, t->by, t->bx);
1316
1317
293k
        if (mvstack[0].mv.mv[0].n)
1318
282k
            b->mv[0] = mvstack[0].mv.mv[0];
1319
11.4k
        else if (mvstack[1].mv.mv[0].n)
1320
0
            b->mv[0] = mvstack[1].mv.mv[0];
1321
11.4k
        else {
1322
11.4k
            if (t->by - (16 << f->seq_hdr->sb128) < ts->tiling.row_start) {
1323
6.61k
                b->mv[0].y = 0;
1324
6.61k
                b->mv[0].x = -(512 << f->seq_hdr->sb128) - 2048;
1325
6.61k
            } else {
1326
4.79k
                b->mv[0].y = -(512 << f->seq_hdr->sb128);
1327
4.79k
                b->mv[0].x = 0;
1328
4.79k
            }
1329
11.4k
        }
1330
1331
293k
        const union mv ref = b->mv[0];
1332
293k
        read_mv_residual(ts, &b->mv[0], -1);
1333
1334
        // clip intrabc motion vector to decoded parts of current tile
1335
293k
        int border_left = ts->tiling.col_start * 4;
1336
293k
        int border_top  = ts->tiling.row_start * 4;
1337
293k
        if (has_chroma) {
1338
231k
            if (bw4 < 2 &&  ss_hor)
1339
14.3k
                border_left += 4;
1340
231k
            if (bh4 < 2 &&  ss_ver)
1341
11.1k
                border_top  += 4;
1342
231k
        }
1343
293k
        int src_left   = t->bx * 4 + (b->mv[0].x >> 3);
1344
293k
        int src_top    = t->by * 4 + (b->mv[0].y >> 3);
1345
293k
        int src_right  = src_left + bw4 * 4;
1346
293k
        int src_bottom = src_top  + bh4 * 4;
1347
293k
        const int border_right = ((ts->tiling.col_end + (bw4 - 1)) & ~(bw4 - 1)) * 4;
1348
1349
        // check against left or right tile boundary and adjust if necessary
1350
293k
        if (src_left < border_left) {
1351
111k
            src_right += border_left - src_left;
1352
111k
            src_left  += border_left - src_left;
1353
182k
        } else if (src_right > border_right) {
1354
109k
            src_left  -= src_right - border_right;
1355
109k
            src_right -= src_right - border_right;
1356
109k
        }
1357
        // check against top tile boundary and adjust if necessary
1358
293k
        if (src_top < border_top) {
1359
263k
            src_bottom += border_top - src_top;
1360
263k
            src_top    += border_top - src_top;
1361
263k
        }
1362
1363
293k
        const int sbx = (t->bx >> (4 + f->seq_hdr->sb128)) << (6 + f->seq_hdr->sb128);
1364
293k
        const int sby = (t->by >> (4 + f->seq_hdr->sb128)) << (6 + f->seq_hdr->sb128);
1365
293k
        const int sb_size = 1 << (6 + f->seq_hdr->sb128);
1366
        // check for overlap with current superblock
1367
293k
        if (src_bottom > sby && src_right > sbx) {
1368
111k
            if (src_top - border_top >= src_bottom - sby) {
1369
                // if possible move src up into the previous suberblock row
1370
5.68k
                src_top    -= src_bottom - sby;
1371
5.68k
                src_bottom -= src_bottom - sby;
1372
105k
            } else if (src_left - border_left >= src_right - sbx) {
1373
                // if possible move src left into the previous suberblock
1374
105k
                src_left  -= src_right - sbx;
1375
105k
                src_right -= src_right - sbx;
1376
105k
            }
1377
111k
        }
1378
        // move src up if it is below current superblock row
1379
293k
        if (src_bottom > sby + sb_size) {
1380
208
            src_top    -= src_bottom - (sby + sb_size);
1381
208
            src_bottom -= src_bottom - (sby + sb_size);
1382
208
        }
1383
        // error out if mv still overlaps with the current superblock
1384
293k
        if (src_bottom > sby && src_right > sbx)
1385
127
            return -1;
1386
1387
293k
        b->mv[0].x = (src_left - t->bx * 4) * 8;
1388
293k
        b->mv[0].y = (src_top  - t->by * 4) * 8;
1389
1390
293k
        if (DEBUG_BLOCK_INFO)
1391
0
            printf("Post-dmv[%d/%d,ref=%d/%d|%d/%d]: r=%d\n",
1392
0
                   b->mv[0].y, b->mv[0].x, ref.y, ref.x,
1393
0
                   mvstack[0].mv.mv[0].y, mvstack[0].mv.mv[0].x, ts->msac.rng);
1394
293k
        read_vartx_tree(t, b, bs, bx4, by4);
1395
1396
        // reconstruction
1397
294k
        if (t->frame_thread.pass == 1) {
1398
294k
            f->bd_fn.read_coef_blocks(t, bs, b);
1399
294k
            b->filter2d = FILTER_2D_BILINEAR;
1400
18.4E
        } else {
1401
18.4E
            if (f->bd_fn.recon_b_inter(t, bs, b)) return -1;
1402
18.4E
        }
1403
1404
293k
        splat_intrabc_mv(f->c, t, bs, b, bw4, bh4);
1405
293k
        BlockContext *edge = t->a;
1406
882k
        for (int i = 0, off = bx4; i < 2; i++, off = by4, edge = &t->l) {
1407
588k
#define set_ctx(rep_macro) \
1408
588k
            rep_macro(edge->tx_intra, off, b_dim[2 + i]); \
1409
588k
            rep_macro(edge->mode, off, DC_PRED); \
1410
588k
            rep_macro(edge->pal_sz, off, 0); \
1411
            /* see aomedia bug 2183 for why this is outside if (has_chroma) */ \
1412
588k
            rep_macro(t->pal_sz_uv[i], off, 0); \
1413
588k
            rep_macro(edge->seg_pred, off, seg_pred); \
1414
588k
            rep_macro(edge->skip_mode, off, 0); \
1415
588k
            rep_macro(edge->intra, off, 0); \
1416
588k
            rep_macro(edge->skip, off, b->skip)
1417
588k
            case_set(b_dim[2 + i]);
1418
588k
#undef set_ctx
1419
588k
        }
1420
293k
        if (has_chroma) {
1421
231k
            dav1d_memset_pow2[ulog2(cbw4)](&t->a->uvmode[cbx4], DC_PRED);
1422
231k
            dav1d_memset_pow2[ulog2(cbh4)](&t->l.uvmode[cby4], DC_PRED);
1423
231k
        }
1424
293k
    } else {
1425
        // inter-specific mode/mv coding
1426
270k
        int is_comp, has_subpel_filter;
1427
1428
270k
        if (b->skip_mode) {
1429
551
            is_comp = 1;
1430
269k
        } else if ((!seg || (seg->ref == -1 && !seg->globalmv && !seg->skip)) &&
1431
218k
                   f->frame_hdr->switchable_comp_refs && imin(bw4, bh4) > 1)
1432
83.5k
        {
1433
83.5k
            const int ctx = get_comp_ctx(t->a, &t->l, by4, bx4,
1434
83.5k
                                         have_top, have_left);
1435
83.5k
            is_comp = dav1d_msac_decode_bool_adapt(&ts->msac,
1436
83.5k
                          ts->cdf.m.comp[ctx]);
1437
83.5k
            if (DEBUG_BLOCK_INFO)
1438
0
                printf("Post-compflag[%d]: r=%d\n", is_comp, ts->msac.rng);
1439
186k
        } else {
1440
186k
            is_comp = 0;
1441
186k
        }
1442
1443
270k
        if (b->skip_mode) {
1444
551
            b->ref[0] = f->frame_hdr->skip_mode_refs[0];
1445
551
            b->ref[1] = f->frame_hdr->skip_mode_refs[1];
1446
551
            b->comp_type = COMP_INTER_AVG;
1447
551
            b->inter_mode = NEARESTMV_NEARESTMV;
1448
551
            b->drl_idx = NEAREST_DRL;
1449
551
            has_subpel_filter = 0;
1450
1451
551
            refmvs_candidate mvstack[8];
1452
551
            int n_mvs, ctx;
1453
551
            dav1d_refmvs_find(&t->rt, mvstack, &n_mvs, &ctx,
1454
551
                              (union refmvs_refpair) { .ref = {
1455
551
                                    b->ref[0] + 1, b->ref[1] + 1 }},
1456
551
                              bs, intra_edge_flags, t->by, t->bx);
1457
1458
551
            b->mv[0] = mvstack[0].mv.mv[0];
1459
551
            b->mv[1] = mvstack[0].mv.mv[1];
1460
551
            fix_mv_precision(f->frame_hdr, &b->mv[0]);
1461
551
            fix_mv_precision(f->frame_hdr, &b->mv[1]);
1462
551
            if (DEBUG_BLOCK_INFO)
1463
0
                printf("Post-skipmodeblock[mv=1:y=%d,x=%d,2:y=%d,x=%d,refs=%d+%d\n",
1464
0
                       b->mv[0].y, b->mv[0].x, b->mv[1].y, b->mv[1].x,
1465
0
                       b->ref[0], b->ref[1]);
1466
269k
        } else if (is_comp) {
1467
42.1k
            const int dir_ctx = get_comp_dir_ctx(t->a, &t->l, by4, bx4,
1468
42.1k
                                                 have_top, have_left);
1469
42.1k
            if (dav1d_msac_decode_bool_adapt(&ts->msac,
1470
42.1k
                    ts->cdf.m.comp_dir[dir_ctx]))
1471
34.8k
            {
1472
                // bidir - first reference (fw)
1473
34.8k
                const int ctx1 = av1_get_fwd_ref_ctx(t->a, &t->l, by4, bx4,
1474
34.8k
                                                     have_top, have_left);
1475
34.8k
                if (dav1d_msac_decode_bool_adapt(&ts->msac,
1476
34.8k
                        ts->cdf.m.comp_fwd_ref[0][ctx1]))
1477
14.1k
                {
1478
14.1k
                    const int ctx2 = av1_get_fwd_ref_2_ctx(t->a, &t->l, by4, bx4,
1479
14.1k
                                                           have_top, have_left);
1480
14.1k
                    b->ref[0] = 2 + dav1d_msac_decode_bool_adapt(&ts->msac,
1481
14.1k
                                        ts->cdf.m.comp_fwd_ref[2][ctx2]);
1482
20.6k
                } else {
1483
20.6k
                    const int ctx2 = av1_get_fwd_ref_1_ctx(t->a, &t->l, by4, bx4,
1484
20.6k
                                                           have_top, have_left);
1485
20.6k
                    b->ref[0] = dav1d_msac_decode_bool_adapt(&ts->msac,
1486
20.6k
                                    ts->cdf.m.comp_fwd_ref[1][ctx2]);
1487
20.6k
                }
1488
1489
                // second reference (bw)
1490
34.8k
                const int ctx3 = av1_get_bwd_ref_ctx(t->a, &t->l, by4, bx4,
1491
34.8k
                                                     have_top, have_left);
1492
34.8k
                if (dav1d_msac_decode_bool_adapt(&ts->msac,
1493
34.8k
                        ts->cdf.m.comp_bwd_ref[0][ctx3]))
1494
20.2k
                {
1495
20.2k
                    b->ref[1] = 6;
1496
20.2k
                } else {
1497
14.6k
                    const int ctx4 = av1_get_bwd_ref_1_ctx(t->a, &t->l, by4, bx4,
1498
14.6k
                                                           have_top, have_left);
1499
14.6k
                    b->ref[1] = 4 + dav1d_msac_decode_bool_adapt(&ts->msac,
1500
14.6k
                                        ts->cdf.m.comp_bwd_ref[1][ctx4]);
1501
14.6k
                }
1502
34.8k
            } else {
1503
                // unidir
1504
7.33k
                const int uctx_p = av1_get_uni_p_ctx(t->a, &t->l, by4, bx4,
1505
7.33k
                                                     have_top, have_left);
1506
7.33k
                if (dav1d_msac_decode_bool_adapt(&ts->msac,
1507
7.33k
                        ts->cdf.m.comp_uni_ref[0][uctx_p]))
1508
2.35k
                {
1509
2.35k
                    b->ref[0] = 4;
1510
2.35k
                    b->ref[1] = 6;
1511
4.98k
                } else {
1512
4.98k
                    const int uctx_p1 = av1_get_uni_p1_ctx(t->a, &t->l, by4, bx4,
1513
4.98k
                                                           have_top, have_left);
1514
4.98k
                    b->ref[0] = 0;
1515
4.98k
                    b->ref[1] = 1 + dav1d_msac_decode_bool_adapt(&ts->msac,
1516
4.98k
                                        ts->cdf.m.comp_uni_ref[1][uctx_p1]);
1517
4.98k
                    if (b->ref[1] == 2) {
1518
3.08k
                        const int uctx_p2 = av1_get_uni_p2_ctx(t->a, &t->l, by4, bx4,
1519
3.08k
                                                               have_top, have_left);
1520
3.08k
                        b->ref[1] += dav1d_msac_decode_bool_adapt(&ts->msac,
1521
3.08k
                                         ts->cdf.m.comp_uni_ref[2][uctx_p2]);
1522
3.08k
                    }
1523
4.98k
                }
1524
7.33k
            }
1525
42.1k
            if (DEBUG_BLOCK_INFO)
1526
0
                printf("Post-refs[%d/%d]: r=%d\n",
1527
0
                       b->ref[0], b->ref[1], ts->msac.rng);
1528
1529
42.1k
            refmvs_candidate mvstack[8];
1530
42.1k
            int n_mvs, ctx;
1531
42.1k
            dav1d_refmvs_find(&t->rt, mvstack, &n_mvs, &ctx,
1532
42.1k
                              (union refmvs_refpair) { .ref = {
1533
42.1k
                                    b->ref[0] + 1, b->ref[1] + 1 }},
1534
42.1k
                              bs, intra_edge_flags, t->by, t->bx);
1535
1536
42.1k
            b->inter_mode = dav1d_msac_decode_symbol_adapt8(&ts->msac,
1537
42.1k
                                ts->cdf.m.comp_inter_mode[ctx],
1538
42.1k
                                N_COMP_INTER_PRED_MODES - 1);
1539
42.1k
            if (DEBUG_BLOCK_INFO)
1540
0
                printf("Post-compintermode[%d,ctx=%d,n_mvs=%d]: r=%d\n",
1541
0
                       b->inter_mode, ctx, n_mvs, ts->msac.rng);
1542
1543
42.1k
            const uint8_t *const im = dav1d_comp_inter_pred_modes[b->inter_mode];
1544
42.1k
            b->drl_idx = NEAREST_DRL;
1545
42.1k
            if (b->inter_mode == NEWMV_NEWMV) {
1546
9.55k
                if (n_mvs > 1) { // NEARER, NEAR or NEARISH
1547
9.55k
                    const int drl_ctx_v1 = get_drl_context(mvstack, 0);
1548
9.55k
                    b->drl_idx += dav1d_msac_decode_bool_adapt(&ts->msac,
1549
9.55k
                                      ts->cdf.m.drl_bit[drl_ctx_v1]);
1550
9.55k
                    if (b->drl_idx == NEARER_DRL && n_mvs > 2) {
1551
956
                        const int drl_ctx_v2 = get_drl_context(mvstack, 1);
1552
956
                        b->drl_idx += dav1d_msac_decode_bool_adapt(&ts->msac,
1553
956
                                          ts->cdf.m.drl_bit[drl_ctx_v2]);
1554
956
                    }
1555
9.55k
                    if (DEBUG_BLOCK_INFO)
1556
0
                        printf("Post-drlidx[%d,n_mvs=%d]: r=%d\n",
1557
0
                               b->drl_idx, n_mvs, ts->msac.rng);
1558
9.55k
                }
1559
32.6k
            } else if (im[0] == NEARMV || im[1] == NEARMV) {
1560
9.31k
                b->drl_idx = NEARER_DRL;
1561
9.31k
                if (n_mvs > 2) { // NEAR or NEARISH
1562
576
                    const int drl_ctx_v2 = get_drl_context(mvstack, 1);
1563
576
                    b->drl_idx += dav1d_msac_decode_bool_adapt(&ts->msac,
1564
576
                                      ts->cdf.m.drl_bit[drl_ctx_v2]);
1565
576
                    if (b->drl_idx == NEAR_DRL && n_mvs > 3) {
1566
71
                        const int drl_ctx_v3 = get_drl_context(mvstack, 2);
1567
71
                        b->drl_idx += dav1d_msac_decode_bool_adapt(&ts->msac,
1568
71
                                          ts->cdf.m.drl_bit[drl_ctx_v3]);
1569
71
                    }
1570
576
                    if (DEBUG_BLOCK_INFO)
1571
0
                        printf("Post-drlidx[%d,n_mvs=%d]: r=%d\n",
1572
0
                               b->drl_idx, n_mvs, ts->msac.rng);
1573
576
                }
1574
9.31k
            }
1575
42.1k
            assert(b->drl_idx >= NEAREST_DRL && b->drl_idx <= NEARISH_DRL);
1576
1577
42.1k
#define assign_comp_mv(idx) \
1578
84.3k
            switch (im[idx]) { \
1579
16.0k
            case NEARMV: \
1580
48.8k
            case NEARESTMV: \
1581
48.8k
                b->mv[idx] = mvstack[b->drl_idx].mv.mv[idx]; \
1582
48.8k
                fix_mv_precision(f->frame_hdr, &b->mv[idx]); \
1583
48.8k
                break; \
1584
16.0k
            case GLOBALMV: \
1585
9.13k
                has_subpel_filter |= \
1586
9.13k
                    f->frame_hdr->gmv[b->ref[idx]].type == DAV1D_WM_TYPE_TRANSLATION; \
1587
9.13k
                b->mv[idx] = get_gmv_2d(&f->frame_hdr->gmv[b->ref[idx]], \
1588
9.13k
                                        t->bx, t->by, bw4, bh4, f->frame_hdr); \
1589
9.13k
                break; \
1590
26.4k
            case NEWMV: \
1591
26.4k
                b->mv[idx] = mvstack[b->drl_idx].mv.mv[idx]; \
1592
26.4k
                const int mv_prec = f->frame_hdr->hp - f->frame_hdr->force_integer_mv; \
1593
26.4k
                read_mv_residual(ts, &b->mv[idx], mv_prec); \
1594
26.4k
                break; \
1595
84.3k
            }
1596
42.1k
            has_subpel_filter = imin(bw4, bh4) == 1 ||
1597
42.1k
                                b->inter_mode != GLOBALMV_GLOBALMV;
1598
42.1k
            assign_comp_mv(0);
1599
42.1k
            assign_comp_mv(1);
1600
42.1k
#undef assign_comp_mv
1601
42.1k
            if (DEBUG_BLOCK_INFO)
1602
0
                printf("Post-residual_mv[1:y=%d,x=%d,2:y=%d,x=%d]: r=%d\n",
1603
0
                       b->mv[0].y, b->mv[0].x, b->mv[1].y, b->mv[1].x,
1604
0
                       ts->msac.rng);
1605
1606
            // jnt_comp vs. seg vs. wedge
1607
42.1k
            int is_segwedge = 0;
1608
42.1k
            if (f->seq_hdr->masked_compound) {
1609
26.5k
                const int mask_ctx = get_mask_comp_ctx(t->a, &t->l, by4, bx4);
1610
1611
26.5k
                is_segwedge = dav1d_msac_decode_bool_adapt(&ts->msac,
1612
26.5k
                                  ts->cdf.m.mask_comp[mask_ctx]);
1613
26.5k
                if (DEBUG_BLOCK_INFO)
1614
0
                    printf("Post-segwedge_vs_jntavg[%d,ctx=%d]: r=%d\n",
1615
0
                           is_segwedge, mask_ctx, ts->msac.rng);
1616
26.5k
            }
1617
1618
42.1k
            if (!is_segwedge) {
1619
34.4k
                if (f->seq_hdr->jnt_comp) {
1620
13.5k
                    const int jnt_ctx =
1621
13.5k
                        get_jnt_comp_ctx(f->seq_hdr->order_hint_n_bits,
1622
13.5k
                                         f->cur.frame_hdr->frame_offset,
1623
13.5k
                                         f->refp[b->ref[0]].p.frame_hdr->frame_offset,
1624
13.5k
                                         f->refp[b->ref[1]].p.frame_hdr->frame_offset,
1625
13.5k
                                         t->a, &t->l, by4, bx4);
1626
13.5k
                    b->comp_type = COMP_INTER_WEIGHTED_AVG +
1627
13.5k
                                   dav1d_msac_decode_bool_adapt(&ts->msac,
1628
13.5k
                                       ts->cdf.m.jnt_comp[jnt_ctx]);
1629
13.5k
                    if (DEBUG_BLOCK_INFO)
1630
0
                        printf("Post-jnt_comp[%d,ctx=%d[ac:%d,ar:%d,lc:%d,lr:%d]]: r=%d\n",
1631
0
                               b->comp_type == COMP_INTER_AVG,
1632
0
                               jnt_ctx, t->a->comp_type[bx4], t->a->ref[0][bx4],
1633
0
                               t->l.comp_type[by4], t->l.ref[0][by4],
1634
0
                               ts->msac.rng);
1635
20.8k
                } else {
1636
20.8k
                    b->comp_type = COMP_INTER_AVG;
1637
20.8k
                }
1638
34.4k
            } else {
1639
7.79k
                if (wedge_allowed_mask & (1 << bs)) {
1640
6.31k
                    const int ctx = dav1d_wedge_ctx_lut[bs];
1641
6.31k
                    b->comp_type = COMP_INTER_WEDGE -
1642
6.31k
                                   dav1d_msac_decode_bool_adapt(&ts->msac,
1643
6.31k
                                       ts->cdf.m.wedge_comp[ctx]);
1644
6.31k
                    if (b->comp_type == COMP_INTER_WEDGE)
1645
2.25k
                        b->wedge_idx = dav1d_msac_decode_symbol_adapt16(&ts->msac,
1646
2.25k
                                           ts->cdf.m.wedge_idx[ctx], 15);
1647
6.31k
                } else {
1648
1.47k
                    b->comp_type = COMP_INTER_SEG;
1649
1.47k
                }
1650
7.79k
                b->mask_sign = dav1d_msac_decode_bool_equi(&ts->msac);
1651
7.79k
                if (DEBUG_BLOCK_INFO)
1652
0
                    printf("Post-seg/wedge[%d,wedge_idx=%d,sign=%d]: r=%d\n",
1653
0
                           b->comp_type == COMP_INTER_WEDGE,
1654
0
                           b->wedge_idx, b->mask_sign, ts->msac.rng);
1655
7.79k
            }
1656
227k
        } else {
1657
227k
            b->comp_type = COMP_INTER_NONE;
1658
1659
            // ref
1660
227k
            if (seg && seg->ref > 0) {
1661
41.3k
                b->ref[0] = seg->ref - 1;
1662
186k
            } else if (seg && (seg->globalmv || seg->skip)) {
1663
10.4k
                b->ref[0] = 0;
1664
175k
            } else {
1665
175k
                const int ctx1 = av1_get_ref_ctx(t->a, &t->l, by4, bx4,
1666
175k
                                                 have_top, have_left);
1667
175k
                if (dav1d_msac_decode_bool_adapt(&ts->msac,
1668
175k
                                                 ts->cdf.m.ref[0][ctx1]))
1669
105k
                {
1670
105k
                    const int ctx2 = av1_get_ref_2_ctx(t->a, &t->l, by4, bx4,
1671
105k
                                                       have_top, have_left);
1672
105k
                    if (dav1d_msac_decode_bool_adapt(&ts->msac,
1673
105k
                                                     ts->cdf.m.ref[1][ctx2]))
1674
85.0k
                    {
1675
85.0k
                        b->ref[0] = 6;
1676
85.0k
                    } else {
1677
20.0k
                        const int ctx3 = av1_get_ref_6_ctx(t->a, &t->l, by4, bx4,
1678
20.0k
                                                           have_top, have_left);
1679
20.0k
                        b->ref[0] = 4 + dav1d_msac_decode_bool_adapt(&ts->msac,
1680
20.0k
                                            ts->cdf.m.ref[5][ctx3]);
1681
20.0k
                    }
1682
105k
                } else {
1683
70.8k
                    const int ctx2 = av1_get_ref_3_ctx(t->a, &t->l, by4, bx4,
1684
70.8k
                                                       have_top, have_left);
1685
70.8k
                    if (dav1d_msac_decode_bool_adapt(&ts->msac,
1686
70.8k
                                                     ts->cdf.m.ref[2][ctx2]))
1687
22.3k
                    {
1688
22.3k
                        const int ctx3 = av1_get_ref_5_ctx(t->a, &t->l, by4, bx4,
1689
22.3k
                                                           have_top, have_left);
1690
22.3k
                        b->ref[0] = 2 + dav1d_msac_decode_bool_adapt(&ts->msac,
1691
22.3k
                                            ts->cdf.m.ref[4][ctx3]);
1692
48.5k
                    } else {
1693
48.5k
                        const int ctx3 = av1_get_ref_4_ctx(t->a, &t->l, by4, bx4,
1694
48.5k
                                                           have_top, have_left);
1695
48.5k
                        b->ref[0] = dav1d_msac_decode_bool_adapt(&ts->msac,
1696
48.5k
                                        ts->cdf.m.ref[3][ctx3]);
1697
48.5k
                    }
1698
70.8k
                }
1699
175k
                if (DEBUG_BLOCK_INFO)
1700
0
                    printf("Post-ref[%d]: r=%d\n", b->ref[0], ts->msac.rng);
1701
175k
            }
1702
227k
            b->ref[1] = -1;
1703
1704
227k
            refmvs_candidate mvstack[8];
1705
227k
            int n_mvs, ctx;
1706
227k
            dav1d_refmvs_find(&t->rt, mvstack, &n_mvs, &ctx,
1707
227k
                              (union refmvs_refpair) { .ref = { b->ref[0] + 1, -1 }},
1708
227k
                              bs, intra_edge_flags, t->by, t->bx);
1709
1710
            // mode parsing and mv derivation from ref_mvs
1711
227k
            if ((seg && (seg->skip || seg->globalmv)) ||
1712
179k
                dav1d_msac_decode_bool_adapt(&ts->msac,
1713
179k
                                             ts->cdf.m.newmv_mode[ctx & 7]))
1714
180k
            {
1715
180k
                if ((seg && (seg->skip || seg->globalmv)) ||
1716
131k
                    !dav1d_msac_decode_bool_adapt(&ts->msac,
1717
131k
                         ts->cdf.m.globalmv_mode[(ctx >> 3) & 1]))
1718
53.4k
                {
1719
53.4k
                    b->inter_mode = GLOBALMV;
1720
53.4k
                    b->mv[0] = get_gmv_2d(&f->frame_hdr->gmv[b->ref[0]],
1721
53.4k
                                          t->bx, t->by, bw4, bh4, f->frame_hdr);
1722
53.4k
                    has_subpel_filter = imin(bw4, bh4) == 1 ||
1723
34.4k
                        f->frame_hdr->gmv[b->ref[0]].type == DAV1D_WM_TYPE_TRANSLATION;
1724
126k
                } else {
1725
126k
                    has_subpel_filter = 1;
1726
126k
                    if (dav1d_msac_decode_bool_adapt(&ts->msac,
1727
126k
                            ts->cdf.m.refmv_mode[(ctx >> 4) & 15]))
1728
77.1k
                    { // NEAREST, NEARER, NEAR or NEARISH
1729
77.1k
                        b->inter_mode = NEARMV;
1730
77.1k
                        b->drl_idx = NEARER_DRL;
1731
77.1k
                        if (n_mvs > 2) { // NEARER, NEAR or NEARISH
1732
8.34k
                            const int drl_ctx_v2 = get_drl_context(mvstack, 1);
1733
8.34k
                            b->drl_idx += dav1d_msac_decode_bool_adapt(&ts->msac,
1734
8.34k
                                              ts->cdf.m.drl_bit[drl_ctx_v2]);
1735
8.34k
                            if (b->drl_idx == NEAR_DRL && n_mvs > 3) { // NEAR or NEARISH
1736
2.75k
                                const int drl_ctx_v3 =
1737
2.75k
                                    get_drl_context(mvstack, 2);
1738
2.75k
                                b->drl_idx += dav1d_msac_decode_bool_adapt(&ts->msac,
1739
2.75k
                                                  ts->cdf.m.drl_bit[drl_ctx_v3]);
1740
2.75k
                            }
1741
8.34k
                        }
1742
77.1k
                    } else {
1743
49.5k
                        b->inter_mode = NEARESTMV;
1744
49.5k
                        b->drl_idx = NEAREST_DRL;
1745
49.5k
                    }
1746
126k
                    assert(b->drl_idx >= NEAREST_DRL && b->drl_idx <= NEARISH_DRL);
1747
126k
                    b->mv[0] = mvstack[b->drl_idx].mv.mv[0];
1748
126k
                    if (b->drl_idx < NEAR_DRL)
1749
120k
                        fix_mv_precision(f->frame_hdr, &b->mv[0]);
1750
126k
                }
1751
1752
180k
                if (DEBUG_BLOCK_INFO)
1753
0
                    printf("Post-intermode[%d,drl=%d,mv=y:%d,x:%d,n_mvs=%d]: r=%d\n",
1754
0
                           b->inter_mode, b->drl_idx, b->mv[0].y, b->mv[0].x, n_mvs,
1755
0
                           ts->msac.rng);
1756
180k
            } else {
1757
47.5k
                has_subpel_filter = 1;
1758
47.5k
                b->inter_mode = NEWMV;
1759
47.5k
                b->drl_idx = NEAREST_DRL;
1760
47.5k
                if (n_mvs > 1) { // NEARER, NEAR or NEARISH
1761
23.5k
                    const int drl_ctx_v1 = get_drl_context(mvstack, 0);
1762
23.5k
                    b->drl_idx += dav1d_msac_decode_bool_adapt(&ts->msac,
1763
23.5k
                                      ts->cdf.m.drl_bit[drl_ctx_v1]);
1764
23.5k
                    if (b->drl_idx == NEARER_DRL && n_mvs > 2) { // NEAR or NEARISH
1765
2.98k
                        const int drl_ctx_v2 = get_drl_context(mvstack, 1);
1766
2.98k
                        b->drl_idx += dav1d_msac_decode_bool_adapt(&ts->msac,
1767
2.98k
                                          ts->cdf.m.drl_bit[drl_ctx_v2]);
1768
2.98k
                    }
1769
23.5k
                }
1770
47.5k
                assert(b->drl_idx >= NEAREST_DRL && b->drl_idx <= NEARISH_DRL);
1771
47.5k
                if (n_mvs > 1) {
1772
23.5k
                    b->mv[0] = mvstack[b->drl_idx].mv.mv[0];
1773
23.9k
                } else {
1774
23.9k
                    assert(!b->drl_idx);
1775
23.9k
                    b->mv[0] = mvstack[0].mv.mv[0];
1776
23.9k
                    fix_mv_precision(f->frame_hdr, &b->mv[0]);
1777
23.9k
                }
1778
47.5k
                if (DEBUG_BLOCK_INFO)
1779
0
                    printf("Post-intermode[%d,drl=%d]: r=%d\n",
1780
0
                           b->inter_mode, b->drl_idx, ts->msac.rng);
1781
47.5k
                const int mv_prec = f->frame_hdr->hp - f->frame_hdr->force_integer_mv;
1782
47.5k
                read_mv_residual(ts, &b->mv[0], mv_prec);
1783
47.5k
                if (DEBUG_BLOCK_INFO)
1784
0
                    printf("Post-residualmv[mv=y:%d,x:%d]: r=%d\n",
1785
0
                           b->mv[0].y, b->mv[0].x, ts->msac.rng);
1786
47.5k
            }
1787
1788
            // interintra flags
1789
227k
            const int ii_sz_grp = dav1d_ymode_size_context[bs];
1790
227k
            if (f->seq_hdr->inter_intra &&
1791
145k
                interintra_allowed_mask & (1 << bs) &&
1792
58.2k
                dav1d_msac_decode_bool_adapt(&ts->msac,
1793
58.2k
                                             ts->cdf.m.interintra[ii_sz_grp]))
1794
9.74k
            {
1795
9.74k
                b->interintra_mode = dav1d_msac_decode_symbol_adapt4(&ts->msac,
1796
9.74k
                                         ts->cdf.m.interintra_mode[ii_sz_grp],
1797
9.74k
                                         N_INTER_INTRA_PRED_MODES - 1);
1798
9.74k
                const int wedge_ctx = dav1d_wedge_ctx_lut[bs];
1799
9.74k
                b->interintra_type = INTER_INTRA_BLEND +
1800
9.74k
                                     dav1d_msac_decode_bool_adapt(&ts->msac,
1801
9.74k
                                         ts->cdf.m.interintra_wedge[wedge_ctx]);
1802
9.74k
                if (b->interintra_type == INTER_INTRA_WEDGE)
1803
2.32k
                    b->wedge_idx = dav1d_msac_decode_symbol_adapt16(&ts->msac,
1804
2.32k
                                       ts->cdf.m.wedge_idx[wedge_ctx], 15);
1805
217k
            } else {
1806
217k
                b->interintra_type = INTER_INTRA_NONE;
1807
217k
            }
1808
227k
            if (DEBUG_BLOCK_INFO && f->seq_hdr->inter_intra &&
1809
0
                interintra_allowed_mask & (1 << bs))
1810
0
            {
1811
0
                printf("Post-interintra[t=%d,m=%d,w=%d]: r=%d\n",
1812
0
                       b->interintra_type, b->interintra_mode,
1813
0
                       b->wedge_idx, ts->msac.rng);
1814
0
            }
1815
1816
            // motion variation
1817
227k
            if (f->frame_hdr->switchable_motion_mode &&
1818
141k
                b->interintra_type == INTER_INTRA_NONE && imin(bw4, bh4) >= 2 &&
1819
                // is not warped global motion
1820
61.6k
                !(!f->frame_hdr->force_integer_mv && b->inter_mode == GLOBALMV &&
1821
23.2k
                  f->frame_hdr->gmv[b->ref[0]].type > DAV1D_WM_TYPE_TRANSLATION) &&
1822
                // has overlappable neighbours
1823
51.2k
                ((have_left && findoddzero(&t->l.intra[by4 + 1], h4 >> 1)) ||
1824
18.8k
                 (have_top && findoddzero(&t->a->intra[bx4 + 1], w4 >> 1))))
1825
46.6k
            {
1826
                // reaching here means the block allows obmc - check warp by
1827
                // finding matching-ref blocks in top/left edges
1828
46.6k
                uint64_t mask[2] = { 0, 0 };
1829
46.6k
                find_matching_ref(t, intra_edge_flags, bw4, bh4, w4, h4,
1830
46.6k
                                  have_left, have_top, b->ref[0], mask);
1831
46.6k
                const int allow_warp = !f->svc[b->ref[0]][0].scale &&
1832
26.2k
                    !f->frame_hdr->force_integer_mv &&
1833
19.6k
                    f->frame_hdr->warp_motion && (mask[0] | mask[1]);
1834
1835
46.6k
                b->motion_mode = allow_warp ?
1836
5.11k
                    dav1d_msac_decode_symbol_adapt4(&ts->msac,
1837
5.11k
                        ts->cdf.m.motion_mode[bs], 2) :
1838
46.6k
                    dav1d_msac_decode_bool_adapt(&ts->msac, ts->cdf.m.obmc[bs]);
1839
46.6k
                if (b->motion_mode == MM_WARP) {
1840
2.14k
                    has_subpel_filter = 0;
1841
2.14k
                    derive_warpmv(t, bw4, bh4, mask, b->mv[0], &t->warpmv);
1842
2.14k
#define signabs(v) v < 0 ? '-' : ' ', abs(v)
1843
2.14k
                    if (DEBUG_BLOCK_INFO)
1844
0
                        printf("[ %c%x %c%x %c%x\n  %c%x %c%x %c%x ]\n"
1845
0
                               "alpha=%c%x, beta=%c%x, gamma=%c%x, delta=%c%x, "
1846
0
                               "mv=y:%d,x:%d\n",
1847
0
                               signabs(t->warpmv.matrix[0]),
1848
0
                               signabs(t->warpmv.matrix[1]),
1849
0
                               signabs(t->warpmv.matrix[2]),
1850
0
                               signabs(t->warpmv.matrix[3]),
1851
0
                               signabs(t->warpmv.matrix[4]),
1852
0
                               signabs(t->warpmv.matrix[5]),
1853
0
                               signabs(t->warpmv.u.p.alpha),
1854
0
                               signabs(t->warpmv.u.p.beta),
1855
0
                               signabs(t->warpmv.u.p.gamma),
1856
0
                               signabs(t->warpmv.u.p.delta),
1857
0
                               b->mv[0].y, b->mv[0].x);
1858
2.14k
#undef signabs
1859
2.14k
                    if (t->frame_thread.pass) {
1860
2.14k
                        if (t->warpmv.type == DAV1D_WM_TYPE_AFFINE) {
1861
1.68k
                            b->matrix[0] = t->warpmv.matrix[2] - 0x10000;
1862
1.68k
                            b->matrix[1] = t->warpmv.matrix[3];
1863
1.68k
                            b->matrix[2] = t->warpmv.matrix[4];
1864
1.68k
                            b->matrix[3] = t->warpmv.matrix[5] - 0x10000;
1865
1.68k
                        } else {
1866
460
                            b->matrix[0] = INT16_MIN;
1867
460
                        }
1868
2.14k
                    }
1869
2.14k
                }
1870
1871
46.6k
                if (DEBUG_BLOCK_INFO)
1872
0
                    printf("Post-motionmode[%d]: r=%d [mask: 0x%" PRIx64 "/0x%"
1873
0
                           PRIx64 "]\n", b->motion_mode, ts->msac.rng, mask[0],
1874
0
                            mask[1]);
1875
181k
            } else {
1876
181k
                b->motion_mode = MM_TRANSLATION;
1877
181k
            }
1878
227k
        }
1879
1880
        // subpel filter
1881
270k
        enum Dav1dFilterMode filter[2];
1882
270k
        if (f->frame_hdr->subpel_filter_mode == DAV1D_FILTER_SWITCHABLE) {
1883
146k
            if (has_subpel_filter) {
1884
121k
                const int comp = b->comp_type != COMP_INTER_NONE;
1885
121k
                const int ctx1 = get_filter_ctx(t->a, &t->l, comp, 0, b->ref[0],
1886
121k
                                                by4, bx4);
1887
121k
                filter[0] = dav1d_msac_decode_symbol_adapt4(&ts->msac,
1888
121k
                               ts->cdf.m.filter[0][ctx1],
1889
121k
                               DAV1D_N_SWITCHABLE_FILTERS - 1);
1890
121k
                if (f->seq_hdr->dual_filter) {
1891
68.9k
                    const int ctx2 = get_filter_ctx(t->a, &t->l, comp, 1,
1892
68.9k
                                                    b->ref[0], by4, bx4);
1893
68.9k
                    if (DEBUG_BLOCK_INFO)
1894
0
                        printf("Post-subpel_filter1[%d,ctx=%d]: r=%d\n",
1895
0
                               filter[0], ctx1, ts->msac.rng);
1896
68.9k
                    filter[1] = dav1d_msac_decode_symbol_adapt4(&ts->msac,
1897
68.9k
                                    ts->cdf.m.filter[1][ctx2],
1898
68.9k
                                    DAV1D_N_SWITCHABLE_FILTERS - 1);
1899
68.9k
                    if (DEBUG_BLOCK_INFO)
1900
0
                        printf("Post-subpel_filter2[%d,ctx=%d]: r=%d\n",
1901
0
                               filter[1], ctx2, ts->msac.rng);
1902
68.9k
                } else {
1903
52.2k
                    filter[1] = filter[0];
1904
52.2k
                    if (DEBUG_BLOCK_INFO)
1905
0
                        printf("Post-subpel_filter[%d,ctx=%d]: r=%d\n",
1906
0
                               filter[0], ctx1, ts->msac.rng);
1907
52.2k
                }
1908
121k
            } else {
1909
25.0k
                filter[0] = filter[1] = DAV1D_FILTER_8TAP_REGULAR;
1910
25.0k
            }
1911
146k
        } else {
1912
124k
            filter[0] = filter[1] = f->frame_hdr->subpel_filter_mode;
1913
124k
        }
1914
270k
        b->filter2d = dav1d_filter_2d[filter[1]][filter[0]];
1915
1916
270k
        read_vartx_tree(t, b, bs, bx4, by4);
1917
1918
        // reconstruction
1919
270k
        if (t->frame_thread.pass == 1) {
1920
270k
            f->bd_fn.read_coef_blocks(t, bs, b);
1921
18.4E
        } else {
1922
18.4E
            if (f->bd_fn.recon_b_inter(t, bs, b)) return -1;
1923
18.4E
        }
1924
1925
270k
        if (f->frame_hdr->loopfilter.level_y[0] ||
1926
80.6k
            f->frame_hdr->loopfilter.level_y[1])
1927
204k
        {
1928
204k
            const int is_globalmv =
1929
204k
                b->inter_mode == (is_comp ? GLOBALMV_GLOBALMV : GLOBALMV);
1930
204k
            const uint8_t (*const lf_lvls)[8][2] = (const uint8_t (*)[8][2])
1931
204k
                &ts->lflvl[b->seg_id][0][b->ref[0] + 1][!is_globalmv];
1932
204k
            const uint16_t tx_split[2] = { b->tx_split0, b->tx_split1 };
1933
204k
            enum RectTxfmSize ytx = b->max_ytx, uvtx = b->uvtx;
1934
204k
            if (f->frame_hdr->segmentation.lossless[b->seg_id]) {
1935
4.16k
                ytx  = (enum RectTxfmSize) TX_4X4;
1936
4.16k
                uvtx = (enum RectTxfmSize) TX_4X4;
1937
4.16k
            }
1938
204k
            dav1d_create_lf_mask_inter(t->lf_mask, f->lf.level, f->b4_stride, lf_lvls,
1939
204k
                                       t->bx, t->by, f->w4, f->h4, b->skip, bs,
1940
204k
                                       ytx, tx_split, uvtx, f->cur.p.layout,
1941
204k
                                       &t->a->tx_lpf_y[bx4], &t->l.tx_lpf_y[by4],
1942
204k
                                       has_chroma ? &t->a->tx_lpf_uv[cbx4] : NULL,
1943
204k
                                       has_chroma ? &t->l.tx_lpf_uv[cby4] : NULL);
1944
204k
        }
1945
1946
        // context updates
1947
270k
        if (is_comp)
1948
42.7k
            splat_tworef_mv(f->c, t, bs, b, bw4, bh4);
1949
227k
        else
1950
227k
            splat_oneref_mv(f->c, t, bs, b, bw4, bh4);
1951
270k
        BlockContext *edge = t->a;
1952
812k
        for (int i = 0, off = bx4; i < 2; i++, off = by4, edge = &t->l) {
1953
541k
#define set_ctx(rep_macro) \
1954
541k
            rep_macro(edge->seg_pred, off, seg_pred); \
1955
541k
            rep_macro(edge->skip_mode, off, b->skip_mode); \
1956
541k
            rep_macro(edge->intra, off, 0); \
1957
541k
            rep_macro(edge->skip, off, b->skip); \
1958
541k
            rep_macro(edge->pal_sz, off, 0); \
1959
            /* see aomedia bug 2183 for why this is outside if (has_chroma) */ \
1960
541k
            rep_macro(t->pal_sz_uv[i], off, 0); \
1961
541k
            rep_macro(edge->tx_intra, off, b_dim[2 + i]); \
1962
541k
            rep_macro(edge->comp_type, off, b->comp_type); \
1963
541k
            rep_macro(edge->filter[0], off, filter[0]); \
1964
541k
            rep_macro(edge->filter[1], off, filter[1]); \
1965
541k
            rep_macro(edge->mode, off, b->inter_mode); \
1966
541k
            rep_macro(edge->ref[0], off, b->ref[0]); \
1967
541k
            rep_macro(edge->ref[1], off, ((uint8_t) b->ref[1]))
1968
541k
            case_set(b_dim[2 + i]);
1969
541k
#undef set_ctx
1970
541k
        }
1971
270k
        if (has_chroma) {
1972
121k
            dav1d_memset_pow2[ulog2(cbw4)](&t->a->uvmode[cbx4], DC_PRED);
1973
121k
            dav1d_memset_pow2[ulog2(cbh4)](&t->l.uvmode[cby4], DC_PRED);
1974
121k
        }
1975
270k
    }
1976
1977
    // update contexts
1978
1.29M
    if (f->frame_hdr->segmentation.enabled &&
1979
610k
        f->frame_hdr->segmentation.update_map)
1980
572k
    {
1981
572k
        uint8_t *seg_ptr = &f->cur_segmap[t->by * f->b4_stride + t->bx];
1982
572k
#define set_ctx(rep_macro) \
1983
2.62M
        for (int y = 0; y < bh4; y++) { \
1984
2.05M
            rep_macro(seg_ptr, 0, b->seg_id); \
1985
2.05M
            seg_ptr += f->b4_stride; \
1986
2.05M
        }
1987
572k
        case_set(b_dim[2]);
1988
571k
#undef set_ctx
1989
571k
    }
1990
1.29M
    if (!b->skip) {
1991
486k
        uint16_t (*noskip_mask)[2] = &t->lf_mask->noskip_mask[by4 >> 1];
1992
486k
        const unsigned mask = (~0U >> (32 - bw4)) << (bx4 & 15);
1993
486k
        const int bx_idx = (bx4 & 16) >> 4;
1994
1.64M
        for (int y = 0; y < bh4; y += 2, noskip_mask++) {
1995
1.16M
            (*noskip_mask)[bx_idx] |= mask;
1996
1.16M
            if (bw4 == 32) // this should be mask >> 16, but it's 0xffffffff anyway
1997
70.0k
                (*noskip_mask)[1] |= mask;
1998
1.16M
        }
1999
486k
    }
2000
2001
1.29M
    if (t->frame_thread.pass == 1 && !b->intra && IS_INTER_OR_SWITCH(f->frame_hdr)) {
2002
270k
        const int sby = (t->by - ts->tiling.row_start) >> f->sb_shift;
2003
270k
        int (*const lowest_px)[2] = ts->lowest_pixel[sby];
2004
2005
        // keep track of motion vectors for each reference
2006
270k
        if (b->comp_type == COMP_INTER_NONE) {
2007
            // y
2008
228k
            if (imin(bw4, bh4) > 1 &&
2009
104k
                ((b->inter_mode == GLOBALMV && f->gmv_warp_allowed[b->ref[0]]) ||
2010
93.9k
                 (b->motion_mode == MM_WARP && t->warpmv.type > DAV1D_WM_TYPE_TRANSLATION)))
2011
11.8k
            {
2012
11.8k
                affine_lowest_px_luma(t, &lowest_px[b->ref[0]][0], b_dim,
2013
11.8k
                                      b->motion_mode == MM_WARP ? &t->warpmv :
2014
11.8k
                                      &f->frame_hdr->gmv[b->ref[0]]);
2015
216k
            } else {
2016
216k
                mc_lowest_px(&lowest_px[b->ref[0]][0], t->by, bh4, b->mv[0].y,
2017
216k
                             0, &f->svc[b->ref[0]][1]);
2018
216k
                if (b->motion_mode == MM_OBMC) {
2019
25.3k
                    obmc_lowest_px(t, lowest_px, 0, b_dim, bx4, by4, w4, h4);
2020
25.3k
                }
2021
216k
            }
2022
2023
            // uv
2024
228k
            if (has_chroma) {
2025
                // sub8x8 derivation
2026
100k
                int is_sub8x8 = bw4 == ss_hor || bh4 == ss_ver;
2027
100k
                refmvs_block *const *r;
2028
100k
                if (is_sub8x8) {
2029
23.1k
                    assert(ss_hor == 1);
2030
23.1k
                    r = &t->rt.r[(t->by & 31) + 5];
2031
23.1k
                    if (bw4 == 1) is_sub8x8 &= r[0][t->bx - 1].ref.ref[0] > 0;
2032
23.1k
                    if (bh4 == ss_ver) is_sub8x8 &= r[-1][t->bx].ref.ref[0] > 0;
2033
23.1k
                    if (bw4 == 1 && bh4 == ss_ver)
2034
8.37k
                        is_sub8x8 &= r[-1][t->bx - 1].ref.ref[0] > 0;
2035
23.1k
                }
2036
2037
                // chroma prediction
2038
100k
                if (is_sub8x8) {
2039
21.8k
                    assert(ss_hor == 1);
2040
21.8k
                    if (bw4 == 1 && bh4 == ss_ver) {
2041
7.37k
                        const refmvs_block *const rr = &r[-1][t->bx - 1];
2042
7.37k
                        mc_lowest_px(&lowest_px[rr->ref.ref[0] - 1][1],
2043
7.37k
                                     t->by - 1, bh4, rr->mv.mv[0].y, ss_ver,
2044
7.37k
                                     &f->svc[rr->ref.ref[0] - 1][1]);
2045
7.37k
                    }
2046
21.8k
                    if (bw4 == 1) {
2047
16.1k
                        const refmvs_block *const rr = &r[0][t->bx - 1];
2048
16.1k
                        mc_lowest_px(&lowest_px[rr->ref.ref[0] - 1][1],
2049
16.1k
                                     t->by, bh4, rr->mv.mv[0].y, ss_ver,
2050
16.1k
                                     &f->svc[rr->ref.ref[0] - 1][1]);
2051
16.1k
                    }
2052
21.8k
                    if (bh4 == ss_ver) {
2053
13.0k
                        const refmvs_block *const rr = &r[-1][t->bx];
2054
13.0k
                        mc_lowest_px(&lowest_px[rr->ref.ref[0] - 1][1],
2055
13.0k
                                     t->by - 1, bh4, rr->mv.mv[0].y, ss_ver,
2056
13.0k
                                     &f->svc[rr->ref.ref[0] - 1][1]);
2057
13.0k
                    }
2058
21.8k
                    mc_lowest_px(&lowest_px[b->ref[0]][1], t->by, bh4,
2059
21.8k
                                 b->mv[0].y, ss_ver, &f->svc[b->ref[0]][1]);
2060
78.6k
                } else {
2061
78.6k
                    if (imin(cbw4, cbh4) > 1 &&
2062
27.1k
                        ((b->inter_mode == GLOBALMV && f->gmv_warp_allowed[b->ref[0]]) ||
2063
21.9k
                         (b->motion_mode == MM_WARP && t->warpmv.type > DAV1D_WM_TYPE_TRANSLATION)))
2064
5.88k
                    {
2065
5.88k
                        affine_lowest_px_chroma(t, &lowest_px[b->ref[0]][1], b_dim,
2066
5.88k
                                                b->motion_mode == MM_WARP ? &t->warpmv :
2067
5.88k
                                                &f->frame_hdr->gmv[b->ref[0]]);
2068
72.7k
                    } else {
2069
72.7k
                        mc_lowest_px(&lowest_px[b->ref[0]][1],
2070
72.7k
                                     t->by & ~ss_ver, bh4 << (bh4 == ss_ver),
2071
72.7k
                                     b->mv[0].y, ss_ver, &f->svc[b->ref[0]][1]);
2072
72.7k
                        if (b->motion_mode == MM_OBMC) {
2073
13.3k
                            obmc_lowest_px(t, lowest_px, 1, b_dim, bx4, by4, w4, h4);
2074
13.3k
                        }
2075
72.7k
                    }
2076
78.6k
                }
2077
100k
            }
2078
228k
        } else {
2079
            // y
2080
128k
            for (int i = 0; i < 2; i++) {
2081
85.4k
                if (b->inter_mode == GLOBALMV_GLOBALMV && f->gmv_warp_allowed[b->ref[i]]) {
2082
933
                    affine_lowest_px_luma(t, &lowest_px[b->ref[i]][0], b_dim,
2083
933
                                          &f->frame_hdr->gmv[b->ref[i]]);
2084
84.5k
                } else {
2085
84.5k
                    mc_lowest_px(&lowest_px[b->ref[i]][0], t->by, bh4,
2086
84.5k
                                 b->mv[i].y, 0, &f->svc[b->ref[i]][1]);
2087
84.5k
                }
2088
85.4k
            }
2089
2090
            // uv
2091
61.8k
            if (has_chroma) for (int i = 0; i < 2; i++) {
2092
41.2k
                if (b->inter_mode == GLOBALMV_GLOBALMV &&
2093
4.40k
                    imin(cbw4, cbh4) > 1 && f->gmv_warp_allowed[b->ref[i]])
2094
232
                {
2095
232
                    affine_lowest_px_chroma(t, &lowest_px[b->ref[i]][1], b_dim,
2096
232
                                            &f->frame_hdr->gmv[b->ref[i]]);
2097
40.9k
                } else {
2098
40.9k
                    mc_lowest_px(&lowest_px[b->ref[i]][1], t->by, bh4,
2099
40.9k
                                 b->mv[i].y, ss_ver, &f->svc[b->ref[i]][1]);
2100
40.9k
                }
2101
41.2k
            }
2102
42.7k
        }
2103
270k
    }
2104
2105
1.29M
    return 0;
2106
1.29M
}
2107
2108
#if __has_feature(memory_sanitizer)
2109
2110
#include <sanitizer/msan_interface.h>
2111
2112
static int checked_decode_b(Dav1dTaskContext *const t,
2113
                            const enum BlockLevel bl,
2114
                            const enum BlockSize bs,
2115
                            const enum BlockPartition bp,
2116
                            const enum EdgeFlags intra_edge_flags)
2117
{
2118
    const Dav1dFrameContext *const f = t->f;
2119
    const int err = decode_b(t, bl, bs, bp, intra_edge_flags);
2120
2121
    if (err == 0 && !(t->frame_thread.pass & 1)) {
2122
        const int ss_ver = f->cur.p.layout == DAV1D_PIXEL_LAYOUT_I420;
2123
        const int ss_hor = f->cur.p.layout != DAV1D_PIXEL_LAYOUT_I444;
2124
        const uint8_t *const b_dim = dav1d_block_dimensions[bs];
2125
        const int bw4 = b_dim[0], bh4 = b_dim[1];
2126
        const int w4 = imin(bw4, f->bw - t->bx), h4 = imin(bh4, f->bh - t->by);
2127
        const int has_chroma = f->seq_hdr->layout != DAV1D_PIXEL_LAYOUT_I400 &&
2128
                               (bw4 > ss_hor || t->bx & 1) &&
2129
                               (bh4 > ss_ver || t->by & 1);
2130
2131
        for (int p = 0; p < 1 + 2 * has_chroma; p++) {
2132
            const int ss_ver = p && f->cur.p.layout == DAV1D_PIXEL_LAYOUT_I420;
2133
            const int ss_hor = p && f->cur.p.layout != DAV1D_PIXEL_LAYOUT_I444;
2134
            const ptrdiff_t stride = f->cur.stride[!!p];
2135
            const int bx = t->bx & ~ss_hor;
2136
            const int by = t->by & ~ss_ver;
2137
            const int width  = w4 << (2 - ss_hor + (bw4 == ss_hor));
2138
            const int height = h4 << (2 - ss_ver + (bh4 == ss_ver));
2139
2140
            const uint8_t *data = f->cur.data[p] + (by << (2 - ss_ver)) * stride +
2141
                                  (bx << (2 - ss_hor + !!f->seq_hdr->hbd));
2142
2143
            for (int y = 0; y < height; data += stride, y++) {
2144
                const size_t line_sz = width << !!f->seq_hdr->hbd;
2145
                if (__msan_test_shadow(data, line_sz) != -1) {
2146
                    fprintf(stderr, "B[%d](%d, %d) w4:%d, h4:%d, row:%d\n",
2147
                            p, bx, by, w4, h4, y);
2148
                    __msan_check_mem_is_initialized(data, line_sz);
2149
                }
2150
            }
2151
        }
2152
    }
2153
2154
    return err;
2155
}
2156
2157
#define decode_b checked_decode_b
2158
2159
#endif /* defined(__has_feature) */
2160
2161
static int decode_sb(Dav1dTaskContext *const t, const enum BlockLevel bl,
2162
                     const EdgeNode *const node)
2163
1.59M
{
2164
1.59M
    const Dav1dFrameContext *const f = t->f;
2165
1.59M
    Dav1dTileState *const ts = t->ts;
2166
1.59M
    const int hsz = 16 >> bl;
2167
1.59M
    const int have_h_split = f->bw > t->bx + hsz;
2168
1.59M
    const int have_v_split = f->bh > t->by + hsz;
2169
2170
1.59M
    if (!have_h_split && !have_v_split) {
2171
63.5k
        assert(bl < BL_8X8);
2172
63.5k
        return decode_sb(t, bl + 1, INTRA_EDGE_SPLIT(node, 0));
2173
63.5k
    }
2174
2175
1.53M
    uint16_t *pc;
2176
1.53M
    enum BlockPartition bp;
2177
1.53M
    int ctx, bx8, by8;
2178
1.53M
    if (t->frame_thread.pass != 2) {
2179
1.08M
        if (0 && bl == BL_64X64)
2180
0
            printf("poc=%d,y=%d,x=%d,bl=%d,r=%d\n",
2181
0
                   f->frame_hdr->frame_offset, t->by, t->bx, bl, ts->msac.rng);
2182
1.08M
        bx8 = (t->bx & 31) >> 1;
2183
1.08M
        by8 = (t->by & 31) >> 1;
2184
1.08M
        ctx = get_partition_ctx(t->a, &t->l, bl, by8, bx8);
2185
1.08M
        pc = ts->cdf.m.partition[bl][ctx];
2186
1.08M
    }
2187
2188
1.53M
    if (have_h_split && have_v_split) {
2189
601k
        if (t->frame_thread.pass == 2) {
2190
166k
            const Av1Block *const b = &f->frame_thread.b[t->by * f->b4_stride + t->bx];
2191
166k
            bp = b->bl == bl ? b->bp : PARTITION_SPLIT;
2192
435k
        } else {
2193
435k
            bp = dav1d_msac_decode_symbol_adapt16(&ts->msac, pc,
2194
435k
                                                  dav1d_partition_type_count[bl]);
2195
435k
            if (f->cur.p.layout == DAV1D_PIXEL_LAYOUT_I422 &&
2196
6.51k
                (bp == PARTITION_V || bp == PARTITION_V4 ||
2197
6.43k
                 bp == PARTITION_T_LEFT_SPLIT || bp == PARTITION_T_RIGHT_SPLIT))
2198
86
            {
2199
86
                return 1;
2200
86
            }
2201
435k
            if (DEBUG_BLOCK_INFO)
2202
0
                printf("poc=%d,y=%d,x=%d,bl=%d,ctx=%d,bp=%d: r=%d\n",
2203
0
                       f->frame_hdr->frame_offset, t->by, t->bx, bl, ctx, bp,
2204
0
                       ts->msac.rng);
2205
435k
        }
2206
601k
        const uint8_t *const b = dav1d_block_sizes[bl][bp];
2207
2208
601k
        switch (bp) {
2209
216k
        case PARTITION_NONE:
2210
216k
            if (decode_b(t, bl, b[0], PARTITION_NONE, node->o))
2211
10
                return -1;
2212
216k
            break;
2213
216k
        case PARTITION_H:
2214
68.9k
            if (decode_b(t, bl, b[0], PARTITION_H, node->h[0]))
2215
6
                return -1;
2216
68.9k
            t->by += hsz;
2217
68.9k
            if (decode_b(t, bl, b[0], PARTITION_H, node->h[1]))
2218
6
                return -1;
2219
68.9k
            t->by -= hsz;
2220
68.9k
            break;
2221
52.7k
        case PARTITION_V:
2222
52.7k
            if (decode_b(t, bl, b[0], PARTITION_V, node->v[0]))
2223
8
                return -1;
2224
52.7k
            t->bx += hsz;
2225
52.7k
            if (decode_b(t, bl, b[0], PARTITION_V, node->v[1]))
2226
7
                return -1;
2227
52.7k
            t->bx -= hsz;
2228
52.7k
            break;
2229
209k
        case PARTITION_SPLIT:
2230
209k
            if (bl == BL_8X8) {
2231
166k
                const EdgeTip *const tip = (const EdgeTip *) node;
2232
166k
                assert(hsz == 1);
2233
166k
                if (decode_b(t, bl, BS_4x4, PARTITION_SPLIT, EDGE_ALL_TR_AND_BL))
2234
7
                    return -1;
2235
166k
                const enum Filter2d tl_filter = t->tl_4x4_filter;
2236
166k
                t->bx++;
2237
166k
                if (decode_b(t, bl, BS_4x4, PARTITION_SPLIT, tip->split[0]))
2238
5
                    return -1;
2239
166k
                t->bx--;
2240
166k
                t->by++;
2241
166k
                if (decode_b(t, bl, BS_4x4, PARTITION_SPLIT, tip->split[1]))
2242
3
                    return -1;
2243
166k
                t->bx++;
2244
166k
                t->tl_4x4_filter = tl_filter;
2245
166k
                if (decode_b(t, bl, BS_4x4, PARTITION_SPLIT, tip->split[2]))
2246
4
                    return -1;
2247
166k
                t->bx--;
2248
166k
                t->by--;
2249
166k
#if ARCH_X86_64
2250
166k
                if (t->frame_thread.pass) {
2251
                    /* In 8-bit mode with 2-pass decoding the coefficient buffer
2252
                     * can end up misaligned due to skips here. Work around
2253
                     * the issue by explicitly realigning the buffer. */
2254
166k
                    const int p = t->frame_thread.pass & 1;
2255
166k
                    ts->frame_thread[p].cf =
2256
166k
                        (void*)(((uintptr_t)ts->frame_thread[p].cf + 63) & ~63);
2257
166k
                }
2258
166k
#endif
2259
166k
            } else {
2260
42.9k
                if (decode_sb(t, bl + 1, INTRA_EDGE_SPLIT(node, 0)))
2261
30
                    return 1;
2262
42.9k
                t->bx += hsz;
2263
42.9k
                if (decode_sb(t, bl + 1, INTRA_EDGE_SPLIT(node, 1)))
2264
31
                    return 1;
2265
42.8k
                t->bx -= hsz;
2266
42.8k
                t->by += hsz;
2267
42.8k
                if (decode_sb(t, bl + 1, INTRA_EDGE_SPLIT(node, 2)))
2268
26
                    return 1;
2269
42.8k
                t->bx += hsz;
2270
42.8k
                if (decode_sb(t, bl + 1, INTRA_EDGE_SPLIT(node, 3)))
2271
19
                    return 1;
2272
42.8k
                t->bx -= hsz;
2273
42.8k
                t->by -= hsz;
2274
42.8k
            }
2275
209k
            break;
2276
209k
        case PARTITION_T_TOP_SPLIT: {
2277
5.39k
            if (decode_b(t, bl, b[0], PARTITION_T_TOP_SPLIT, EDGE_ALL_TR_AND_BL))
2278
3
                return -1;
2279
5.39k
            t->bx += hsz;
2280
5.39k
            if (decode_b(t, bl, b[0], PARTITION_T_TOP_SPLIT, node->v[1]))
2281
3
                return -1;
2282
5.38k
            t->bx -= hsz;
2283
5.38k
            t->by += hsz;
2284
5.38k
            if (decode_b(t, bl, b[1], PARTITION_T_TOP_SPLIT, node->h[1]))
2285
3
                return -1;
2286
5.38k
            t->by -= hsz;
2287
5.38k
            break;
2288
5.38k
        }
2289
6.24k
        case PARTITION_T_BOTTOM_SPLIT: {
2290
6.24k
            if (decode_b(t, bl, b[0], PARTITION_T_BOTTOM_SPLIT, node->h[0]))
2291
3
                return -1;
2292
6.24k
            t->by += hsz;
2293
6.24k
            if (decode_b(t, bl, b[1], PARTITION_T_BOTTOM_SPLIT, node->v[0]))
2294
3
                return -1;
2295
6.24k
            t->bx += hsz;
2296
6.24k
            if (decode_b(t, bl, b[1], PARTITION_T_BOTTOM_SPLIT, 0))
2297
3
                return -1;
2298
6.24k
            t->bx -= hsz;
2299
6.24k
            t->by -= hsz;
2300
6.24k
            break;
2301
6.24k
        }
2302
4.39k
        case PARTITION_T_LEFT_SPLIT: {
2303
4.39k
            if (decode_b(t, bl, b[0], PARTITION_T_LEFT_SPLIT, EDGE_ALL_TR_AND_BL))
2304
3
                return -1;
2305
4.39k
            t->by += hsz;
2306
4.39k
            if (decode_b(t, bl, b[0], PARTITION_T_LEFT_SPLIT, node->h[1]))
2307
3
                return -1;
2308
4.38k
            t->by -= hsz;
2309
4.38k
            t->bx += hsz;
2310
4.38k
            if (decode_b(t, bl, b[1], PARTITION_T_LEFT_SPLIT, node->v[1]))
2311
3
                return -1;
2312
4.38k
            t->bx -= hsz;
2313
4.38k
            break;
2314
4.38k
        }
2315
5.46k
        case PARTITION_T_RIGHT_SPLIT: {
2316
5.46k
            if (decode_b(t, bl, b[0], PARTITION_T_RIGHT_SPLIT, node->v[0]))
2317
3
                return -1;
2318
5.45k
            t->bx += hsz;
2319
5.45k
            if (decode_b(t, bl, b[1], PARTITION_T_RIGHT_SPLIT, node->h[0]))
2320
3
                return -1;
2321
5.45k
            t->by += hsz;
2322
5.45k
            if (decode_b(t, bl, b[1], PARTITION_T_RIGHT_SPLIT, 0))
2323
3
                return -1;
2324
5.45k
            t->by -= hsz;
2325
5.45k
            t->bx -= hsz;
2326
5.45k
            break;
2327
5.45k
        }
2328
12.0k
        case PARTITION_H4: {
2329
12.0k
            const EdgeBranch *const branch = (const EdgeBranch *) node;
2330
12.0k
            if (decode_b(t, bl, b[0], PARTITION_H4, node->h[0]))
2331
3
                return -1;
2332
12.0k
            t->by += hsz >> 1;
2333
12.0k
            if (decode_b(t, bl, b[0], PARTITION_H4, branch->h4))
2334
4
                return -1;
2335
12.0k
            t->by += hsz >> 1;
2336
12.0k
            if (decode_b(t, bl, b[0], PARTITION_H4, EDGE_ALL_LEFT_HAS_BOTTOM))
2337
3
                return -1;
2338
12.0k
            t->by += hsz >> 1;
2339
12.0k
            if (t->by < f->bh)
2340
11.0k
                if (decode_b(t, bl, b[0], PARTITION_H4, node->h[1]))
2341
3
                    return -1;
2342
12.0k
            t->by -= hsz * 3 >> 1;
2343
12.0k
            break;
2344
12.0k
        }
2345
20.3k
        case PARTITION_V4: {
2346
20.3k
            const EdgeBranch *const branch = (const EdgeBranch *) node;
2347
20.3k
            if (decode_b(t, bl, b[0], PARTITION_V4, node->v[0]))
2348
5
                return -1;
2349
20.3k
            t->bx += hsz >> 1;
2350
20.3k
            if (decode_b(t, bl, b[0], PARTITION_V4, branch->v4))
2351
4
                return -1;
2352
20.3k
            t->bx += hsz >> 1;
2353
20.3k
            if (decode_b(t, bl, b[0], PARTITION_V4, EDGE_ALL_TOP_HAS_RIGHT))
2354
2
                return -1;
2355
20.3k
            t->bx += hsz >> 1;
2356
20.3k
            if (t->bx < f->bw)
2357
18.6k
                if (decode_b(t, bl, b[0], PARTITION_V4, node->v[1]))
2358
3
                    return -1;
2359
20.3k
            t->bx -= hsz * 3 >> 1;
2360
20.3k
            break;
2361
20.3k
        }
2362
0
        default: assert(0);
2363
601k
        }
2364
934k
    } else if (have_h_split) {
2365
515k
        unsigned is_split;
2366
515k
        if (t->frame_thread.pass == 2) {
2367
89.5k
            const Av1Block *const b = &f->frame_thread.b[t->by * f->b4_stride + t->bx];
2368
89.5k
            is_split = b->bl != bl;
2369
426k
        } else {
2370
426k
            is_split = dav1d_msac_decode_bool(&ts->msac,
2371
426k
                           gather_top_partition_prob(pc, bl));
2372
426k
            if (DEBUG_BLOCK_INFO)
2373
0
                printf("poc=%d,y=%d,x=%d,bl=%d,ctx=%d,bp=%d: r=%d\n",
2374
0
                       f->frame_hdr->frame_offset, t->by, t->bx, bl, ctx,
2375
0
                       is_split ? PARTITION_SPLIT : PARTITION_H, ts->msac.rng);
2376
426k
        }
2377
2378
515k
        assert(bl < BL_8X8);
2379
515k
        if (is_split) {
2380
303k
            bp = PARTITION_SPLIT;
2381
303k
            if (decode_sb(t, bl + 1, INTRA_EDGE_SPLIT(node, 0))) return 1;
2382
302k
            t->bx += hsz;
2383
302k
            if (decode_sb(t, bl + 1, INTRA_EDGE_SPLIT(node, 1))) return 1;
2384
302k
            t->bx -= hsz;
2385
302k
        } else {
2386
212k
            bp = PARTITION_H;
2387
212k
            if (decode_b(t, bl, dav1d_block_sizes[bl][PARTITION_H][0],
2388
212k
                         PARTITION_H, node->h[0]))
2389
5
                return -1;
2390
212k
        }
2391
515k
    } else {
2392
418k
        assert(have_v_split);
2393
418k
        unsigned is_split;
2394
418k
        if (t->frame_thread.pass == 2) {
2395
196k
            const Av1Block *const b = &f->frame_thread.b[t->by * f->b4_stride + t->bx];
2396
196k
            is_split = b->bl != bl;
2397
222k
        } else {
2398
222k
            is_split = dav1d_msac_decode_bool(&ts->msac,
2399
222k
                           gather_left_partition_prob(pc, bl));
2400
222k
            if (f->cur.p.layout == DAV1D_PIXEL_LAYOUT_I422 && !is_split)
2401
22
                return 1;
2402
222k
            if (DEBUG_BLOCK_INFO)
2403
0
                printf("poc=%d,y=%d,x=%d,bl=%d,ctx=%d,bp=%d: r=%d\n",
2404
0
                       f->frame_hdr->frame_offset, t->by, t->bx, bl, ctx,
2405
0
                       is_split ? PARTITION_SPLIT : PARTITION_V, ts->msac.rng);
2406
222k
        }
2407
2408
418k
        assert(bl < BL_8X8);
2409
418k
        if (is_split) {
2410
212k
            bp = PARTITION_SPLIT;
2411
212k
            if (decode_sb(t, bl + 1, INTRA_EDGE_SPLIT(node, 0))) return 1;
2412
212k
            t->by += hsz;
2413
212k
            if (decode_sb(t, bl + 1, INTRA_EDGE_SPLIT(node, 2))) return 1;
2414
212k
            t->by -= hsz;
2415
212k
        } else {
2416
206k
            bp = PARTITION_V;
2417
206k
            if (decode_b(t, bl, dav1d_block_sizes[bl][PARTITION_V][0],
2418
206k
                         PARTITION_V, node->v[0]))
2419
3
                return -1;
2420
206k
        }
2421
418k
    }
2422
2423
1.53M
    if (t->frame_thread.pass != 2 && (bp != PARTITION_SPLIT || bl == BL_8X8)) {
2424
679k
#define set_ctx(rep_macro) \
2425
680k
        rep_macro(t->a->partition, bx8, dav1d_al_part_ctx[0][bl][bp]); \
2426
680k
        rep_macro(t->l.partition, by8, dav1d_al_part_ctx[1][bl][bp])
2427
680k
        case_set_upto16(ulog2(hsz));
2428
680k
#undef set_ctx
2429
680k
    }
2430
2431
1.53M
    return 0;
2432
1.53M
}
2433
2434
378k
static void reset_context(BlockContext *const ctx, const int keyframe, const int pass) {
2435
378k
    memset(ctx->intra, keyframe, sizeof(ctx->intra));
2436
378k
    memset(ctx->uvmode, DC_PRED, sizeof(ctx->uvmode));
2437
378k
    if (keyframe)
2438
290k
        memset(ctx->mode, DC_PRED, sizeof(ctx->mode));
2439
2440
378k
    if (pass == 2) return;
2441
2442
195k
    memset(ctx->partition, 0, sizeof(ctx->partition));
2443
195k
    memset(ctx->skip, 0, sizeof(ctx->skip));
2444
195k
    memset(ctx->skip_mode, 0, sizeof(ctx->skip_mode));
2445
195k
    memset(ctx->tx_lpf_y, 2, sizeof(ctx->tx_lpf_y));
2446
195k
    memset(ctx->tx_lpf_uv, 1, sizeof(ctx->tx_lpf_uv));
2447
195k
    memset(ctx->tx_intra, -1, sizeof(ctx->tx_intra));
2448
195k
    memset(ctx->tx, TX_64X64, sizeof(ctx->tx));
2449
195k
    if (!keyframe) {
2450
44.9k
        memset(ctx->ref, -1, sizeof(ctx->ref));
2451
44.9k
        memset(ctx->comp_type, 0, sizeof(ctx->comp_type));
2452
44.9k
        memset(ctx->mode, NEARESTMV, sizeof(ctx->mode));
2453
44.9k
    }
2454
195k
    memset(ctx->lcoef, 0x40, sizeof(ctx->lcoef));
2455
195k
    memset(ctx->ccoef, 0x40, sizeof(ctx->ccoef));
2456
195k
    memset(ctx->filter, DAV1D_N_SWITCHABLE_FILTERS, sizeof(ctx->filter));
2457
195k
    memset(ctx->seg_pred, 0, sizeof(ctx->seg_pred));
2458
195k
    memset(ctx->pal_sz, 0, sizeof(ctx->pal_sz));
2459
195k
}
2460
2461
// { Y+U+V, Y+U } * 4
2462
static const uint8_t ss_size_mul[4][2] = {
2463
    [DAV1D_PIXEL_LAYOUT_I400] = {  4, 4 },
2464
    [DAV1D_PIXEL_LAYOUT_I420] = {  6, 5 },
2465
    [DAV1D_PIXEL_LAYOUT_I422] = {  8, 6 },
2466
    [DAV1D_PIXEL_LAYOUT_I444] = { 12, 8 },
2467
};
2468
2469
static void setup_tile(Dav1dTileState *const ts,
2470
                       const Dav1dFrameContext *const f,
2471
                       const uint8_t *const data, const size_t sz,
2472
                       const int tile_row, const int tile_col,
2473
                       const unsigned tile_start_off)
2474
31.5k
{
2475
31.5k
    const int col_sb_start = f->frame_hdr->tiling.col_start_sb[tile_col];
2476
31.5k
    const int col_sb128_start = col_sb_start >> !f->seq_hdr->sb128;
2477
31.5k
    const int col_sb_end = f->frame_hdr->tiling.col_start_sb[tile_col + 1];
2478
31.5k
    const int row_sb_start = f->frame_hdr->tiling.row_start_sb[tile_row];
2479
31.5k
    const int row_sb_end = f->frame_hdr->tiling.row_start_sb[tile_row + 1];
2480
31.5k
    const int sb_shift = f->sb_shift;
2481
2482
31.5k
    const uint8_t *const size_mul = ss_size_mul[f->cur.p.layout];
2483
94.5k
    for (int p = 0; p < 2; p++) {
2484
63.0k
        ts->frame_thread[p].pal_idx = f->frame_thread.pal_idx ?
2485
32.7k
            &f->frame_thread.pal_idx[(size_t)tile_start_off * size_mul[1] / 8] :
2486
63.0k
            NULL;
2487
63.0k
        ts->frame_thread[p].cbi = f->frame_thread.cbi ?
2488
63.0k
            &f->frame_thread.cbi[(size_t)tile_start_off * size_mul[0] / 64] :
2489
63.0k
            NULL;
2490
63.0k
        ts->frame_thread[p].cf = f->frame_thread.cf ?
2491
63.0k
            (uint8_t*)f->frame_thread.cf +
2492
63.0k
                (((size_t)tile_start_off * size_mul[0]) >> !f->seq_hdr->hbd) :
2493
63.0k
            NULL;
2494
63.0k
    }
2495
2496
31.5k
    dav1d_cdf_thread_copy(&ts->cdf, &f->in_cdf);
2497
31.5k
    ts->last_qidx = f->frame_hdr->quant.yac;
2498
31.5k
    ts->last_delta_lf.u32 = 0;
2499
2500
31.5k
    dav1d_msac_init(&ts->msac, data, sz, f->frame_hdr->disable_cdf_update);
2501
2502
31.5k
    ts->tiling.row = tile_row;
2503
31.5k
    ts->tiling.col = tile_col;
2504
31.5k
    ts->tiling.col_start = col_sb_start << sb_shift;
2505
31.5k
    ts->tiling.col_end = imin(col_sb_end << sb_shift, f->bw);
2506
31.5k
    ts->tiling.row_start = row_sb_start << sb_shift;
2507
31.5k
    ts->tiling.row_end = imin(row_sb_end << sb_shift, f->bh);
2508
2509
    // Reference Restoration Unit (used for exp coding)
2510
31.5k
    int sb_idx, unit_idx;
2511
31.5k
    if (f->frame_hdr->width[0] != f->frame_hdr->width[1]) {
2512
        // vertical components only
2513
6.16k
        sb_idx = (ts->tiling.row_start >> 5) * f->sr_sb128w;
2514
6.16k
        unit_idx = (ts->tiling.row_start & 16) >> 3;
2515
25.3k
    } else {
2516
25.3k
        sb_idx = (ts->tiling.row_start >> 5) * f->sb128w + col_sb128_start;
2517
25.3k
        unit_idx = ((ts->tiling.row_start & 16) >> 3) +
2518
25.3k
                   ((ts->tiling.col_start & 16) >> 4);
2519
25.3k
    }
2520
126k
    for (int p = 0; p < 3; p++) {
2521
94.5k
        if (!((f->lf.restore_planes >> p) & 1U))
2522
69.8k
            continue;
2523
2524
24.7k
        if (f->frame_hdr->width[0] != f->frame_hdr->width[1]) {
2525
5.80k
            const int ss_hor = p && f->cur.p.layout != DAV1D_PIXEL_LAYOUT_I444;
2526
5.80k
            const int d = f->frame_hdr->super_res.width_scale_denominator;
2527
5.80k
            const int unit_size_log2 = f->frame_hdr->restoration.unit_size[!!p];
2528
5.80k
            const int rnd = (8 << unit_size_log2) - 1, shift = unit_size_log2 + 3;
2529
5.80k
            const int x = ((4 * ts->tiling.col_start * d >> ss_hor) + rnd) >> shift;
2530
5.80k
            const int px_x = x << (unit_size_log2 + ss_hor);
2531
5.80k
            const int u_idx = unit_idx + ((px_x & 64) >> 6);
2532
5.80k
            const int sb128x = px_x >> 7;
2533
5.80k
            if (sb128x >= f->sr_sb128w) continue;
2534
5.58k
            ts->lr_ref[p] = &f->lf.lr_mask[sb_idx + sb128x].lr[p][u_idx];
2535
18.9k
        } else {
2536
18.9k
            ts->lr_ref[p] = &f->lf.lr_mask[sb_idx].lr[p][unit_idx];
2537
18.9k
        }
2538
2539
24.4k
        ts->lr_ref[p]->filter_v[0] = 3;
2540
24.4k
        ts->lr_ref[p]->filter_v[1] = -7;
2541
24.4k
        ts->lr_ref[p]->filter_v[2] = 15;
2542
24.4k
        ts->lr_ref[p]->filter_h[0] = 3;
2543
24.4k
        ts->lr_ref[p]->filter_h[1] = -7;
2544
24.4k
        ts->lr_ref[p]->filter_h[2] = 15;
2545
24.4k
        ts->lr_ref[p]->sgr_weights[0] = -32;
2546
24.4k
        ts->lr_ref[p]->sgr_weights[1] = 31;
2547
24.4k
    }
2548
2549
31.5k
    if (f->c->n_tc > 1) {
2550
94.5k
        for (int p = 0; p < 2; p++)
2551
63.0k
            atomic_init(&ts->progress[p], row_sb_start);
2552
31.5k
    }
2553
31.5k
}
2554
2555
static void read_restoration_info(Dav1dTaskContext *const t,
2556
                                  Av1RestorationUnit *const lr, const int p,
2557
                                  const enum Dav1dRestorationType frame_type)
2558
80.7k
{
2559
80.7k
    const Dav1dFrameContext *const f = t->f;
2560
80.7k
    Dav1dTileState *const ts = t->ts;
2561
80.7k
    const Av1RestorationUnit *const lr_ref = ts->lr_ref[p];
2562
2563
80.7k
    if (frame_type == DAV1D_RESTORATION_SWITCHABLE) {
2564
23.5k
        const int filter = dav1d_msac_decode_symbol_adapt4(&ts->msac,
2565
23.5k
                               ts->cdf.m.restore_switchable, 2);
2566
23.5k
        lr->type = filter + !!filter; /* NONE/WIENER/SGRPROJ */
2567
57.2k
    } else {
2568
57.2k
        const unsigned type =
2569
57.2k
            dav1d_msac_decode_bool_adapt(&ts->msac,
2570
57.2k
                frame_type == DAV1D_RESTORATION_WIENER ?
2571
31.2k
                ts->cdf.m.restore_wiener : ts->cdf.m.restore_sgrproj);
2572
57.2k
        lr->type = type ? frame_type : DAV1D_RESTORATION_NONE;
2573
57.2k
    }
2574
2575
80.7k
    if (lr->type == DAV1D_RESTORATION_WIENER) {
2576
23.3k
        lr->filter_v[0] = p ? 0 :
2577
23.3k
            dav1d_msac_decode_subexp(&ts->msac,
2578
9.84k
                lr_ref->filter_v[0] + 5, 16, 1) - 5;
2579
23.3k
        lr->filter_v[1] =
2580
23.3k
            dav1d_msac_decode_subexp(&ts->msac,
2581
23.3k
                lr_ref->filter_v[1] + 23, 32, 2) - 23;
2582
23.3k
        lr->filter_v[2] =
2583
23.3k
            dav1d_msac_decode_subexp(&ts->msac,
2584
23.3k
                lr_ref->filter_v[2] + 17, 64, 3) - 17;
2585
2586
23.3k
        lr->filter_h[0] = p ? 0 :
2587
23.3k
            dav1d_msac_decode_subexp(&ts->msac,
2588
9.84k
                lr_ref->filter_h[0] + 5, 16, 1) - 5;
2589
23.3k
        lr->filter_h[1] =
2590
23.3k
            dav1d_msac_decode_subexp(&ts->msac,
2591
23.3k
                lr_ref->filter_h[1] + 23, 32, 2) - 23;
2592
23.3k
        lr->filter_h[2] =
2593
23.3k
            dav1d_msac_decode_subexp(&ts->msac,
2594
23.3k
                lr_ref->filter_h[2] + 17, 64, 3) - 17;
2595
23.3k
        memcpy(lr->sgr_weights, lr_ref->sgr_weights, sizeof(lr->sgr_weights));
2596
23.3k
        ts->lr_ref[p] = lr;
2597
23.3k
        if (DEBUG_BLOCK_INFO)
2598
0
            printf("Post-lr_wiener[pl=%d,v[%d,%d,%d],h[%d,%d,%d]]: r=%d\n",
2599
0
                   p, lr->filter_v[0], lr->filter_v[1],
2600
0
                   lr->filter_v[2], lr->filter_h[0],
2601
0
                   lr->filter_h[1], lr->filter_h[2], ts->msac.rng);
2602
57.3k
    } else if (lr->type == DAV1D_RESTORATION_SGRPROJ) {
2603
21.3k
        const unsigned idx = dav1d_msac_decode_bools(&ts->msac, 4);
2604
21.3k
        const uint16_t *const sgr_params = dav1d_sgr_params[idx];
2605
21.3k
        lr->type += idx;
2606
21.3k
        lr->sgr_weights[0] = sgr_params[0] ? dav1d_msac_decode_subexp(&ts->msac,
2607
17.1k
            lr_ref->sgr_weights[0] + 96, 128, 4) - 96 : 0;
2608
21.3k
        lr->sgr_weights[1] = sgr_params[1] ? dav1d_msac_decode_subexp(&ts->msac,
2609
14.4k
            lr_ref->sgr_weights[1] + 32, 128, 4) - 32 : 95;
2610
21.3k
        memcpy(lr->filter_v, lr_ref->filter_v, sizeof(lr->filter_v));
2611
21.3k
        memcpy(lr->filter_h, lr_ref->filter_h, sizeof(lr->filter_h));
2612
21.3k
        ts->lr_ref[p] = lr;
2613
21.3k
        if (DEBUG_BLOCK_INFO)
2614
0
            printf("Post-lr_sgrproj[pl=%d,idx=%d,w[%d,%d]]: r=%d\n",
2615
0
                   p, idx, lr->sgr_weights[0],
2616
0
                   lr->sgr_weights[1], ts->msac.rng);
2617
21.3k
    }
2618
80.7k
}
2619
2620
// modeled after the equivalent function in aomdec:decodeframe.c
2621
0
static int check_trailing_bits_after_symbol_coder(const MsacContext *const msac) {
2622
    // check marker bit (single 1), followed by zeroes
2623
0
    const int n_bits = -(msac->cnt + 14);
2624
0
    assert(n_bits <= 0); // this assumes we errored out when cnt <= -15 in caller
2625
0
    const int n_bytes = (n_bits + 7) >> 3;
2626
0
    const uint8_t *p = &msac->buf_pos[n_bytes];
2627
0
    const int pattern = 128 >> ((n_bits - 1) & 7);
2628
0
    if ((p[-1] & (2 * pattern - 1)) != pattern)
2629
0
        return 1;
2630
2631
    // check remainder zero bytes
2632
0
    for (; p < msac->buf_end; p++)
2633
0
        if (*p)
2634
0
            return 1;
2635
2636
0
    return 0;
2637
0
}
2638
2639
182k
int dav1d_decode_tile_sbrow(Dav1dTaskContext *const t) {
2640
182k
    const Dav1dFrameContext *const f = t->f;
2641
182k
    const enum BlockLevel root_bl = f->seq_hdr->sb128 ? BL_128X128 : BL_64X64;
2642
182k
    Dav1dTileState *const ts = t->ts;
2643
182k
    const Dav1dContext *const c = f->c;
2644
182k
    const int sb_step = f->sb_step;
2645
182k
    const int tile_row = ts->tiling.row, tile_col = ts->tiling.col;
2646
182k
    const int col_sb_start = f->frame_hdr->tiling.col_start_sb[tile_col];
2647
182k
    const int col_sb128_start = col_sb_start >> !f->seq_hdr->sb128;
2648
2649
182k
    if (IS_INTER_OR_SWITCH(f->frame_hdr) || f->frame_hdr->allow_intrabc) {
2650
86.4k
        dav1d_refmvs_tile_sbrow_init(&t->rt, &f->rf, ts->tiling.col_start,
2651
86.4k
                                     ts->tiling.col_end, ts->tiling.row_start,
2652
86.4k
                                     ts->tiling.row_end, t->by >> f->sb_shift,
2653
86.4k
                                     ts->tiling.row, t->frame_thread.pass);
2654
86.4k
    }
2655
2656
182k
    if (IS_INTER_OR_SWITCH(f->frame_hdr) && c->n_fc > 1) {
2657
38.5k
        const int sby = (t->by - ts->tiling.row_start) >> f->sb_shift;
2658
38.5k
        int (*const lowest_px)[2] = ts->lowest_pixel[sby];
2659
308k
        for (int n = 0; n < 7; n++)
2660
809k
            for (int m = 0; m < 2; m++)
2661
539k
                lowest_px[n][m] = INT_MIN;
2662
38.5k
    }
2663
2664
182k
    reset_context(&t->l, IS_KEY_OR_INTRA(f->frame_hdr), t->frame_thread.pass);
2665
182k
    if (t->frame_thread.pass == 2) {
2666
84.4k
        const int off_2pass = c->n_tc > 1 ? f->sb128w * f->frame_hdr->tiling.rows : 0;
2667
84.4k
        for (t->bx = ts->tiling.col_start,
2668
84.4k
             t->a = f->a + off_2pass + col_sb128_start + tile_row * f->sb128w;
2669
204k
             t->bx < ts->tiling.col_end; t->bx += sb_step)
2670
119k
        {
2671
119k
            if (atomic_load_explicit(c->flush, memory_order_acquire))
2672
1
                return 1;
2673
119k
            if (decode_sb(t, root_bl, dav1d_intra_edge_tree[root_bl]))
2674
0
                return 1;
2675
119k
            if (t->bx & 16 || f->seq_hdr->sb128)
2676
54.0k
                t->a++;
2677
119k
        }
2678
84.4k
        f->bd_fn.backup_ipred_edge(t);
2679
84.4k
        return 0;
2680
84.4k
    }
2681
2682
98.2k
    if (f->c->n_tc > 1 && f->frame_hdr->use_ref_frame_mvs) {
2683
3.15k
        f->c->refmvs_dsp.load_tmvs(&f->rf, ts->tiling.row,
2684
3.15k
                                   ts->tiling.col_start >> 1, ts->tiling.col_end >> 1,
2685
3.15k
                                   t->by >> 1, (t->by + sb_step) >> 1);
2686
3.15k
    }
2687
98.2k
    memset(t->pal_sz_uv[1], 0, sizeof(*t->pal_sz_uv));
2688
98.2k
    const int sb128y = t->by >> 5;
2689
98.2k
    for (t->bx = ts->tiling.col_start, t->a = f->a + col_sb128_start + tile_row * f->sb128w,
2690
98.2k
         t->lf_mask = f->lf.mask + sb128y * f->sb128w + col_sb128_start;
2691
313k
         t->bx < ts->tiling.col_end; t->bx += sb_step)
2692
215k
    {
2693
215k
        if (atomic_load_explicit(c->flush, memory_order_acquire))
2694
20
            return 1;
2695
215k
        if (root_bl == BL_128X128) {
2696
50.3k
            t->cur_sb_cdef_idx_ptr = t->lf_mask->cdef_idx;
2697
50.3k
            t->cur_sb_cdef_idx_ptr[0] = -1;
2698
50.3k
            t->cur_sb_cdef_idx_ptr[1] = -1;
2699
50.3k
            t->cur_sb_cdef_idx_ptr[2] = -1;
2700
50.3k
            t->cur_sb_cdef_idx_ptr[3] = -1;
2701
165k
        } else {
2702
165k
            t->cur_sb_cdef_idx_ptr =
2703
165k
                &t->lf_mask->cdef_idx[((t->bx & 16) >> 4) +
2704
165k
                                      ((t->by & 16) >> 3)];
2705
165k
            t->cur_sb_cdef_idx_ptr[0] = -1;
2706
165k
        }
2707
        // Restoration filter
2708
863k
        for (int p = 0; p < 3; p++) {
2709
647k
            if (!((f->lf.restore_planes >> p) & 1U))
2710
534k
                continue;
2711
2712
112k
            const int ss_ver = p && f->cur.p.layout == DAV1D_PIXEL_LAYOUT_I420;
2713
112k
            const int ss_hor = p && f->cur.p.layout != DAV1D_PIXEL_LAYOUT_I444;
2714
112k
            const int unit_size_log2 = f->frame_hdr->restoration.unit_size[!!p];
2715
112k
            const int y = t->by * 4 >> ss_ver;
2716
112k
            const int h = (f->cur.p.h + ss_ver) >> ss_ver;
2717
2718
112k
            const int unit_size = 1 << unit_size_log2;
2719
112k
            const unsigned mask = unit_size - 1;
2720
112k
            if (y & mask) continue;
2721
94.1k
            const int half_unit = unit_size >> 1;
2722
            // Round half up at frame boundaries, if there's more than one
2723
            // restoration unit
2724
94.1k
            if (y && y + half_unit > h) continue;
2725
2726
92.6k
            const enum Dav1dRestorationType frame_type = f->frame_hdr->restoration.type[p];
2727
2728
92.6k
            if (f->frame_hdr->width[0] != f->frame_hdr->width[1]) {
2729
26.2k
                const int w = (f->sr_cur.p.p.w + ss_hor) >> ss_hor;
2730
26.2k
                const int n_units = imax(1, (w + half_unit) >> unit_size_log2);
2731
2732
26.2k
                const int d = f->frame_hdr->super_res.width_scale_denominator;
2733
26.2k
                const int rnd = unit_size * 8 - 1, shift = unit_size_log2 + 3;
2734
26.2k
                const int x0 = ((4 *  t->bx            * d >> ss_hor) + rnd) >> shift;
2735
26.2k
                const int x1 = ((4 * (t->bx + sb_step) * d >> ss_hor) + rnd) >> shift;
2736
2737
55.5k
                for (int x = x0; x < imin(x1, n_units); x++) {
2738
29.2k
                    const int px_x = x << (unit_size_log2 + ss_hor);
2739
29.2k
                    const int sb_idx = (t->by >> 5) * f->sr_sb128w + (px_x >> 7);
2740
29.2k
                    const int unit_idx = ((t->by & 16) >> 3) + ((px_x & 64) >> 6);
2741
29.2k
                    Av1RestorationUnit *const lr = &f->lf.lr_mask[sb_idx].lr[p][unit_idx];
2742
2743
29.2k
                    read_restoration_info(t, lr, p, frame_type);
2744
29.2k
                }
2745
66.3k
            } else {
2746
66.3k
                const int x = 4 * t->bx >> ss_hor;
2747
66.3k
                if (x & mask) continue;
2748
52.5k
                const int w = (f->cur.p.w + ss_hor) >> ss_hor;
2749
                // Round half up at frame boundaries, if there's more than one
2750
                // restoration unit
2751
52.5k
                if (x && x + half_unit > w) continue;
2752
51.4k
                const int sb_idx = (t->by >> 5) * f->sr_sb128w + (t->bx >> 5);
2753
51.4k
                const int unit_idx = ((t->by & 16) >> 3) + ((t->bx & 16) >> 4);
2754
51.4k
                Av1RestorationUnit *const lr = &f->lf.lr_mask[sb_idx].lr[p][unit_idx];
2755
2756
51.4k
                read_restoration_info(t, lr, p, frame_type);
2757
51.4k
            }
2758
92.6k
        }
2759
215k
        if (decode_sb(t, root_bl, dav1d_intra_edge_tree[root_bl]))
2760
235
            return 1;
2761
215k
        if (t->bx & 16 || f->seq_hdr->sb128) {
2762
103k
            t->a++;
2763
103k
            t->lf_mask++;
2764
103k
        }
2765
215k
    }
2766
2767
97.9k
    if (f->seq_hdr->ref_frame_mvs && f->c->n_tc > 1 && IS_INTER_OR_SWITCH(f->frame_hdr)) {
2768
7.58k
        dav1d_refmvs_save_tmvs(&f->c->refmvs_dsp, &t->rt,
2769
7.58k
                               ts->tiling.col_start >> 1, ts->tiling.col_end >> 1,
2770
7.58k
                               t->by >> 1, (t->by + sb_step) >> 1);
2771
7.58k
    }
2772
2773
    // backup pre-loopfilter pixels for intra prediction of the next sbrow
2774
97.9k
    if (t->frame_thread.pass != 1)
2775
0
        f->bd_fn.backup_ipred_edge(t);
2776
2777
    // backup t->a/l.tx_lpf_y/uv at tile boundaries to use them to "fix"
2778
    // up the initial value in neighbour tiles when running the loopfilter
2779
97.9k
    int align_h = (f->bh + 31) & ~31;
2780
97.9k
    memcpy(&f->lf.tx_lpf_right_edge[0][align_h * tile_col + t->by],
2781
97.9k
           &t->l.tx_lpf_y[t->by & 16], sb_step);
2782
97.9k
    const int ss_ver = f->cur.p.layout == DAV1D_PIXEL_LAYOUT_I420;
2783
97.9k
    align_h >>= ss_ver;
2784
97.9k
    memcpy(&f->lf.tx_lpf_right_edge[1][align_h * tile_col + (t->by >> ss_ver)],
2785
97.9k
           &t->l.tx_lpf_uv[(t->by & 16) >> ss_ver], sb_step >> ss_ver);
2786
2787
    // error out on symbol decoder overread
2788
97.9k
    if (ts->msac.cnt <= -15) return 1;
2789
2790
93.2k
    return c->strict_std_compliance &&
2791
0
           (t->by >> f->sb_shift) + 1 >= f->frame_hdr->tiling.row_start_sb[tile_row + 1] &&
2792
0
           check_trailing_bits_after_symbol_coder(&ts->msac);
2793
97.9k
}
2794
2795
28.4k
int dav1d_decode_frame_init(Dav1dFrameContext *const f) {
2796
28.4k
    const Dav1dContext *const c = f->c;
2797
28.4k
    int retval = DAV1D_ERR(ENOMEM);
2798
2799
28.4k
    if (f->sbh > f->lf.start_of_tile_row_sz) {
2800
28.3k
        dav1d_free(f->lf.start_of_tile_row);
2801
28.3k
        f->lf.start_of_tile_row = dav1d_malloc(ALLOC_TILE, f->sbh * sizeof(uint8_t));
2802
28.3k
        if (!f->lf.start_of_tile_row) {
2803
0
            f->lf.start_of_tile_row_sz = 0;
2804
0
            goto error;
2805
0
        }
2806
28.3k
        f->lf.start_of_tile_row_sz = f->sbh;
2807
28.3k
    }
2808
28.4k
    int sby = 0;
2809
59.8k
    for (int tile_row = 0; tile_row < f->frame_hdr->tiling.rows; tile_row++) {
2810
31.3k
        f->lf.start_of_tile_row[sby++] = tile_row;
2811
139k
        while (sby < f->frame_hdr->tiling.row_start_sb[tile_row + 1])
2812
107k
            f->lf.start_of_tile_row[sby++] = 0;
2813
31.3k
    }
2814
2815
28.4k
    const int n_ts = f->frame_hdr->tiling.cols * f->frame_hdr->tiling.rows;
2816
28.4k
    if (n_ts != f->n_ts) {
2817
28.3k
        if (c->n_fc > 1) {
2818
28.3k
            dav1d_free(f->frame_thread.tile_start_off);
2819
28.3k
            f->frame_thread.tile_start_off =
2820
28.3k
                dav1d_malloc(ALLOC_TILE, sizeof(*f->frame_thread.tile_start_off) * n_ts);
2821
28.3k
            if (!f->frame_thread.tile_start_off) {
2822
0
                f->n_ts = 0;
2823
0
                goto error;
2824
0
            }
2825
28.3k
        }
2826
28.3k
        dav1d_free_aligned(f->ts);
2827
28.3k
        f->ts = dav1d_alloc_aligned(ALLOC_TILE, sizeof(*f->ts) * n_ts, 32);
2828
28.3k
        if (!f->ts) goto error;
2829
28.3k
        f->n_ts = n_ts;
2830
28.3k
    }
2831
2832
28.4k
    const int a_sz = f->sb128w * f->frame_hdr->tiling.rows * (1 + (c->n_fc > 1 && c->n_tc > 1));
2833
28.4k
    if (a_sz != f->a_sz) {
2834
28.3k
        dav1d_free(f->a);
2835
28.3k
        f->a = dav1d_malloc(ALLOC_TILE, sizeof(*f->a) * a_sz);
2836
28.3k
        if (!f->a) {
2837
0
            f->a_sz = 0;
2838
0
            goto error;
2839
0
        }
2840
28.3k
        f->a_sz = a_sz;
2841
28.3k
    }
2842
2843
28.4k
    const int num_sb128 = f->sb128w * f->sb128h;
2844
28.4k
    const uint8_t *const size_mul = ss_size_mul[f->cur.p.layout];
2845
28.4k
    const int hbd = !!f->seq_hdr->hbd;
2846
28.4k
    if (c->n_fc > 1) {
2847
28.4k
        const unsigned sb_step4 = f->sb_step * 4;
2848
28.4k
        int tile_idx = 0;
2849
59.8k
        for (int tile_row = 0; tile_row < f->frame_hdr->tiling.rows; tile_row++) {
2850
31.3k
            const unsigned row_off = f->frame_hdr->tiling.row_start_sb[tile_row] *
2851
31.3k
                                     sb_step4 * f->sb128w * 128;
2852
31.3k
            const unsigned b_diff = (f->frame_hdr->tiling.row_start_sb[tile_row + 1] -
2853
31.3k
                                     f->frame_hdr->tiling.row_start_sb[tile_row]) * sb_step4;
2854
66.4k
            for (int tile_col = 0; tile_col < f->frame_hdr->tiling.cols; tile_col++) {
2855
35.0k
                f->frame_thread.tile_start_off[tile_idx++] = row_off + b_diff *
2856
35.0k
                    f->frame_hdr->tiling.col_start_sb[tile_col] * sb_step4;
2857
35.0k
            }
2858
31.3k
        }
2859
2860
28.4k
        const int lowest_pixel_mem_sz = f->frame_hdr->tiling.cols * f->sbh;
2861
28.4k
        if (lowest_pixel_mem_sz != f->tile_thread.lowest_pixel_mem_sz) {
2862
28.3k
            dav1d_free(f->tile_thread.lowest_pixel_mem);
2863
28.3k
            f->tile_thread.lowest_pixel_mem =
2864
28.3k
                dav1d_malloc(ALLOC_TILE, lowest_pixel_mem_sz *
2865
28.3k
                             sizeof(*f->tile_thread.lowest_pixel_mem));
2866
28.3k
            if (!f->tile_thread.lowest_pixel_mem) {
2867
0
                f->tile_thread.lowest_pixel_mem_sz = 0;
2868
0
                goto error;
2869
0
            }
2870
28.3k
            f->tile_thread.lowest_pixel_mem_sz = lowest_pixel_mem_sz;
2871
28.3k
        }
2872
28.4k
        int (*lowest_pixel_ptr)[7][2] = f->tile_thread.lowest_pixel_mem;
2873
59.8k
        for (int tile_row = 0, tile_row_base = 0; tile_row < f->frame_hdr->tiling.rows;
2874
31.3k
             tile_row++, tile_row_base += f->frame_hdr->tiling.cols)
2875
31.3k
        {
2876
31.3k
            const int tile_row_sb_h = f->frame_hdr->tiling.row_start_sb[tile_row + 1] -
2877
31.3k
                                      f->frame_hdr->tiling.row_start_sb[tile_row];
2878
66.4k
            for (int tile_col = 0; tile_col < f->frame_hdr->tiling.cols; tile_col++) {
2879
35.0k
                f->ts[tile_row_base + tile_col].lowest_pixel = lowest_pixel_ptr;
2880
35.0k
                lowest_pixel_ptr += tile_row_sb_h;
2881
35.0k
            }
2882
31.3k
        }
2883
2884
28.4k
        const int cbi_sz = num_sb128 * size_mul[0];
2885
28.4k
        if (cbi_sz != f->frame_thread.cbi_sz) {
2886
28.3k
            dav1d_free_aligned(f->frame_thread.cbi);
2887
28.3k
            f->frame_thread.cbi =
2888
28.3k
                dav1d_alloc_aligned(ALLOC_BLOCK, sizeof(*f->frame_thread.cbi) *
2889
28.3k
                                    cbi_sz * 32 * 32 / 4, 64);
2890
28.3k
            if (!f->frame_thread.cbi) {
2891
0
                f->frame_thread.cbi_sz = 0;
2892
0
                goto error;
2893
0
            }
2894
28.3k
            f->frame_thread.cbi_sz = cbi_sz;
2895
28.3k
        }
2896
2897
28.4k
        const int cf_sz = (num_sb128 * size_mul[0]) << hbd;
2898
28.4k
        if (cf_sz != f->frame_thread.cf_sz) {
2899
28.3k
            dav1d_free_aligned(f->frame_thread.cf);
2900
28.3k
            f->frame_thread.cf =
2901
28.3k
                dav1d_alloc_aligned(ALLOC_COEF, (size_t)cf_sz * 128 * 128 / 2, 64);
2902
28.3k
            if (!f->frame_thread.cf) {
2903
0
                f->frame_thread.cf_sz = 0;
2904
0
                goto error;
2905
0
            }
2906
28.3k
            memset(f->frame_thread.cf, 0, (size_t)cf_sz * 128 * 128 / 2);
2907
28.3k
            f->frame_thread.cf_sz = cf_sz;
2908
28.3k
        }
2909
2910
28.4k
        if (f->frame_hdr->allow_screen_content_tools) {
2911
15.5k
            const int pal_sz = num_sb128 << hbd;
2912
15.5k
            if (pal_sz != f->frame_thread.pal_sz) {
2913
15.4k
                dav1d_free_aligned(f->frame_thread.pal);
2914
15.4k
                f->frame_thread.pal =
2915
15.4k
                    dav1d_alloc_aligned(ALLOC_PAL, sizeof(*f->frame_thread.pal) *
2916
15.4k
                                        pal_sz * 16 * 16, 64);
2917
15.4k
                if (!f->frame_thread.pal) {
2918
0
                    f->frame_thread.pal_sz = 0;
2919
0
                    goto error;
2920
0
                }
2921
15.4k
                f->frame_thread.pal_sz = pal_sz;
2922
15.4k
            }
2923
2924
15.5k
            const int pal_idx_sz = num_sb128 * size_mul[1];
2925
15.5k
            if (pal_idx_sz != f->frame_thread.pal_idx_sz) {
2926
15.4k
                dav1d_free_aligned(f->frame_thread.pal_idx);
2927
15.4k
                f->frame_thread.pal_idx =
2928
15.4k
                    dav1d_alloc_aligned(ALLOC_PAL, sizeof(*f->frame_thread.pal_idx) *
2929
15.4k
                                        pal_idx_sz * 128 * 128 / 8, 64);
2930
15.4k
                if (!f->frame_thread.pal_idx) {
2931
0
                    f->frame_thread.pal_idx_sz = 0;
2932
0
                    goto error;
2933
0
                }
2934
15.4k
                f->frame_thread.pal_idx_sz = pal_idx_sz;
2935
15.4k
            }
2936
15.5k
        } else if (f->frame_thread.pal) {
2937
0
            dav1d_freep_aligned(&f->frame_thread.pal);
2938
0
            dav1d_freep_aligned(&f->frame_thread.pal_idx);
2939
0
            f->frame_thread.pal_sz = f->frame_thread.pal_idx_sz = 0;
2940
0
        }
2941
28.4k
    }
2942
2943
    // update allocation of block contexts for above
2944
28.4k
    ptrdiff_t y_stride = f->cur.stride[0], uv_stride = f->cur.stride[1];
2945
28.4k
    const int has_resize = f->frame_hdr->width[0] != f->frame_hdr->width[1];
2946
28.4k
    const int need_cdef_lpf_copy = c->n_tc > 1 && has_resize;
2947
28.4k
    if (y_stride * f->sbh * 4 != f->lf.cdef_buf_plane_sz[0] ||
2948
96
        uv_stride * f->sbh * 8 != f->lf.cdef_buf_plane_sz[1] ||
2949
96
        need_cdef_lpf_copy != f->lf.need_cdef_lpf_copy ||
2950
91
        f->sbh != f->lf.cdef_buf_sbh)
2951
28.3k
    {
2952
28.3k
        dav1d_free_aligned(f->lf.cdef_line_buf);
2953
28.3k
        size_t alloc_sz = 64;
2954
28.3k
        alloc_sz += (size_t)llabs(y_stride) * 4 * f->sbh << need_cdef_lpf_copy;
2955
28.3k
        alloc_sz += (size_t)llabs(uv_stride) * 8 * f->sbh << need_cdef_lpf_copy;
2956
28.3k
        uint8_t *ptr = f->lf.cdef_line_buf = dav1d_alloc_aligned(ALLOC_CDEF, alloc_sz, 32);
2957
28.3k
        if (!ptr) {
2958
0
            f->lf.cdef_buf_plane_sz[0] = f->lf.cdef_buf_plane_sz[1] = 0;
2959
0
            goto error;
2960
0
        }
2961
2962
28.3k
        ptr += 32;
2963
28.3k
        if (y_stride < 0) {
2964
0
            f->lf.cdef_line[0][0] = ptr - y_stride * (f->sbh * 4 - 1);
2965
0
            f->lf.cdef_line[1][0] = ptr - y_stride * (f->sbh * 4 - 3);
2966
28.3k
        } else {
2967
28.3k
            f->lf.cdef_line[0][0] = ptr + y_stride * 0;
2968
28.3k
            f->lf.cdef_line[1][0] = ptr + y_stride * 2;
2969
28.3k
        }
2970
28.3k
        ptr += llabs(y_stride) * f->sbh * 4;
2971
28.3k
        if (uv_stride < 0) {
2972
0
            f->lf.cdef_line[0][1] = ptr - uv_stride * (f->sbh * 8 - 1);
2973
0
            f->lf.cdef_line[0][2] = ptr - uv_stride * (f->sbh * 8 - 3);
2974
0
            f->lf.cdef_line[1][1] = ptr - uv_stride * (f->sbh * 8 - 5);
2975
0
            f->lf.cdef_line[1][2] = ptr - uv_stride * (f->sbh * 8 - 7);
2976
28.3k
        } else {
2977
28.3k
            f->lf.cdef_line[0][1] = ptr + uv_stride * 0;
2978
28.3k
            f->lf.cdef_line[0][2] = ptr + uv_stride * 2;
2979
28.3k
            f->lf.cdef_line[1][1] = ptr + uv_stride * 4;
2980
28.3k
            f->lf.cdef_line[1][2] = ptr + uv_stride * 6;
2981
28.3k
        }
2982
2983
28.3k
        if (need_cdef_lpf_copy) {
2984
5.80k
            ptr += llabs(uv_stride) * f->sbh * 8;
2985
5.80k
            if (y_stride < 0)
2986
0
                f->lf.cdef_lpf_line[0] = ptr - y_stride * (f->sbh * 4 - 1);
2987
5.80k
            else
2988
5.80k
                f->lf.cdef_lpf_line[0] = ptr;
2989
5.80k
            ptr += llabs(y_stride) * f->sbh * 4;
2990
5.80k
            if (uv_stride < 0) {
2991
0
                f->lf.cdef_lpf_line[1] = ptr - uv_stride * (f->sbh * 4 - 1);
2992
0
                f->lf.cdef_lpf_line[2] = ptr - uv_stride * (f->sbh * 8 - 1);
2993
5.80k
            } else {
2994
5.80k
                f->lf.cdef_lpf_line[1] = ptr;
2995
5.80k
                f->lf.cdef_lpf_line[2] = ptr + uv_stride * f->sbh * 4;
2996
5.80k
            }
2997
5.80k
        }
2998
2999
28.3k
        f->lf.cdef_buf_plane_sz[0] = (int) y_stride * f->sbh * 4;
3000
28.3k
        f->lf.cdef_buf_plane_sz[1] = (int) uv_stride * f->sbh * 8;
3001
28.3k
        f->lf.need_cdef_lpf_copy = need_cdef_lpf_copy;
3002
28.3k
        f->lf.cdef_buf_sbh = f->sbh;
3003
28.3k
    }
3004
3005
28.4k
    const int sb128 = f->seq_hdr->sb128;
3006
28.4k
    const int num_lines = c->n_tc > 1 ? f->sbh * 4 << sb128 : 12;
3007
28.4k
    y_stride = f->sr_cur.p.stride[0], uv_stride = f->sr_cur.p.stride[1];
3008
28.4k
    if (y_stride * num_lines != f->lf.lr_buf_plane_sz[0] ||
3009
96
        uv_stride * num_lines * 2 != f->lf.lr_buf_plane_sz[1])
3010
28.3k
    {
3011
28.3k
        dav1d_free_aligned(f->lf.lr_line_buf);
3012
        // lr simd may overread the input, so slightly over-allocate the lpf buffer
3013
28.3k
        size_t alloc_sz = 128;
3014
28.3k
        alloc_sz += (size_t)llabs(y_stride) * num_lines;
3015
28.3k
        alloc_sz += (size_t)llabs(uv_stride) * num_lines * 2;
3016
28.3k
        uint8_t *ptr = f->lf.lr_line_buf = dav1d_alloc_aligned(ALLOC_LR, alloc_sz, 64);
3017
28.3k
        if (!ptr) {
3018
0
            f->lf.lr_buf_plane_sz[0] = f->lf.lr_buf_plane_sz[1] = 0;
3019
0
            goto error;
3020
0
        }
3021
3022
28.3k
        ptr += 64;
3023
28.3k
        if (y_stride < 0)
3024
0
            f->lf.lr_lpf_line[0] = ptr - y_stride * (num_lines - 1);
3025
28.3k
        else
3026
28.3k
            f->lf.lr_lpf_line[0] = ptr;
3027
28.3k
        ptr += llabs(y_stride) * num_lines;
3028
28.3k
        if (uv_stride < 0) {
3029
0
            f->lf.lr_lpf_line[1] = ptr - uv_stride * (num_lines * 1 - 1);
3030
0
            f->lf.lr_lpf_line[2] = ptr - uv_stride * (num_lines * 2 - 1);
3031
28.3k
        } else {
3032
28.3k
            f->lf.lr_lpf_line[1] = ptr;
3033
28.3k
            f->lf.lr_lpf_line[2] = ptr + uv_stride * num_lines;
3034
28.3k
        }
3035
3036
28.3k
        f->lf.lr_buf_plane_sz[0] = (int) y_stride * num_lines;
3037
28.3k
        f->lf.lr_buf_plane_sz[1] = (int) uv_stride * num_lines * 2;
3038
28.3k
    }
3039
3040
    // update allocation for loopfilter masks
3041
28.4k
    if (num_sb128 != f->lf.mask_sz) {
3042
28.3k
        dav1d_free(f->lf.mask);
3043
28.3k
        dav1d_free(f->lf.level);
3044
28.3k
        f->lf.mask = dav1d_malloc(ALLOC_LF, sizeof(*f->lf.mask) * num_sb128);
3045
        // over-allocate by 3 bytes since some of the SIMD implementations
3046
        // index this from the level type and can thus over-read by up to 3
3047
28.3k
        f->lf.level = dav1d_malloc(ALLOC_LF, sizeof(*f->lf.level) * num_sb128 * 32 * 32 + 3);
3048
28.3k
        if (!f->lf.mask || !f->lf.level) {
3049
0
            f->lf.mask_sz = 0;
3050
0
            goto error;
3051
0
        }
3052
28.3k
        if (c->n_fc > 1) {
3053
28.3k
            dav1d_free(f->frame_thread.b);
3054
28.3k
            f->frame_thread.b = dav1d_malloc(ALLOC_BLOCK, sizeof(*f->frame_thread.b) *
3055
28.3k
                                             num_sb128 * 32 * 32);
3056
28.3k
            if (!f->frame_thread.b) {
3057
0
                f->lf.mask_sz = 0;
3058
0
                goto error;
3059
0
            }
3060
28.3k
        }
3061
28.3k
        f->lf.mask_sz = num_sb128;
3062
28.3k
    }
3063
3064
28.4k
    f->sr_sb128w = (f->sr_cur.p.p.w + 127) >> 7;
3065
28.4k
    const int lr_mask_sz = f->sr_sb128w * f->sb128h;
3066
28.4k
    if (lr_mask_sz != f->lf.lr_mask_sz) {
3067
28.3k
        dav1d_free(f->lf.lr_mask);
3068
28.3k
        f->lf.lr_mask = dav1d_malloc(ALLOC_LR, sizeof(*f->lf.lr_mask) * lr_mask_sz);
3069
28.3k
        if (!f->lf.lr_mask) {
3070
0
            f->lf.lr_mask_sz = 0;
3071
0
            goto error;
3072
0
        }
3073
28.3k
        f->lf.lr_mask_sz = lr_mask_sz;
3074
28.3k
    }
3075
28.4k
    f->lf.restore_planes =
3076
28.4k
        ((f->frame_hdr->restoration.type[0] != DAV1D_RESTORATION_NONE) << 0) +
3077
28.4k
        ((f->frame_hdr->restoration.type[1] != DAV1D_RESTORATION_NONE) << 1) +
3078
28.4k
        ((f->frame_hdr->restoration.type[2] != DAV1D_RESTORATION_NONE) << 2);
3079
28.4k
    if (f->frame_hdr->loopfilter.sharpness != f->lf.last_sharpness) {
3080
28.4k
        dav1d_calc_eih(&f->lf.lim_lut, f->frame_hdr->loopfilter.sharpness);
3081
28.4k
        f->lf.last_sharpness = f->frame_hdr->loopfilter.sharpness;
3082
28.4k
    }
3083
28.4k
    dav1d_calc_lf_values(f->lf.lvl, f->frame_hdr, (int8_t[4]) { 0, 0, 0, 0 });
3084
28.4k
    memset(f->lf.mask, 0, sizeof(*f->lf.mask) * num_sb128);
3085
3086
28.4k
    const int ipred_edge_sz = f->sbh * f->sb128w << hbd;
3087
28.4k
    if (ipred_edge_sz != f->ipred_edge_sz) {
3088
28.3k
        dav1d_free_aligned(f->ipred_edge[0]);
3089
28.3k
        uint8_t *ptr = f->ipred_edge[0] =
3090
28.3k
            dav1d_alloc_aligned(ALLOC_IPRED, ipred_edge_sz * 128 * 3, 64);
3091
28.3k
        if (!ptr) {
3092
0
            f->ipred_edge_sz = 0;
3093
0
            goto error;
3094
0
        }
3095
28.3k
        f->ipred_edge[1] = ptr + ipred_edge_sz * 128 * 1;
3096
28.3k
        f->ipred_edge[2] = ptr + ipred_edge_sz * 128 * 2;
3097
28.3k
        f->ipred_edge_sz = ipred_edge_sz;
3098
28.3k
    }
3099
3100
28.4k
    const int re_sz = f->sb128h * f->frame_hdr->tiling.cols;
3101
28.4k
    if (re_sz != f->lf.re_sz) {
3102
28.3k
        dav1d_free(f->lf.tx_lpf_right_edge[0]);
3103
28.3k
        f->lf.tx_lpf_right_edge[0] = dav1d_malloc(ALLOC_LF, re_sz * 32 * 2);
3104
28.3k
        if (!f->lf.tx_lpf_right_edge[0]) {
3105
0
            f->lf.re_sz = 0;
3106
0
            goto error;
3107
0
        }
3108
28.3k
        f->lf.tx_lpf_right_edge[1] = f->lf.tx_lpf_right_edge[0] + re_sz * 32;
3109
28.3k
        f->lf.re_sz = re_sz;
3110
28.3k
    }
3111
3112
    // init ref mvs
3113
28.4k
    if (IS_INTER_OR_SWITCH(f->frame_hdr) || f->frame_hdr->allow_intrabc) {
3114
14.3k
        const int ret =
3115
14.3k
            dav1d_refmvs_init_frame(&f->rf, f->seq_hdr, f->frame_hdr,
3116
14.3k
                                    f->refpoc, f->mvs, f->refrefpoc, f->ref_mvs,
3117
14.3k
                                    f->c->n_tc, f->c->n_fc);
3118
14.3k
        if (ret < 0) goto error;
3119
14.3k
    }
3120
3121
    // setup dequant tables
3122
28.4k
    init_quant_tables(f->seq_hdr, f->frame_hdr, f->frame_hdr->quant.yac, f->dq);
3123
28.4k
    if (f->frame_hdr->quant.qm)
3124
274k
        for (int i = 0; i < N_RECT_TX_SIZES; i++) {
3125
261k
            f->qm[i][0] = dav1d_qm_tbl[f->frame_hdr->quant.qm_y][0][i];
3126
261k
            f->qm[i][1] = dav1d_qm_tbl[f->frame_hdr->quant.qm_u][1][i];
3127
261k
            f->qm[i][2] = dav1d_qm_tbl[f->frame_hdr->quant.qm_v][1][i];
3128
261k
        }
3129
14.6k
    else
3130
14.6k
        memset(f->qm, 0, sizeof(f->qm));
3131
3132
    // setup jnt_comp weights
3133
28.4k
    if (f->frame_hdr->switchable_comp_refs) {
3134
57.7k
        for (int i = 0; i < 7; i++) {
3135
50.5k
            const unsigned ref0poc = f->refp[i].p.frame_hdr->frame_offset;
3136
3137
201k
            for (int j = i + 1; j < 7; j++) {
3138
151k
                const unsigned ref1poc = f->refp[j].p.frame_hdr->frame_offset;
3139
3140
151k
                const unsigned d1 =
3141
151k
                    imin(abs(get_poc_diff(f->seq_hdr->order_hint_n_bits, ref0poc,
3142
151k
                                          f->cur.frame_hdr->frame_offset)), 31);
3143
151k
                const unsigned d0 =
3144
151k
                    imin(abs(get_poc_diff(f->seq_hdr->order_hint_n_bits, ref1poc,
3145
151k
                                          f->cur.frame_hdr->frame_offset)), 31);
3146
151k
                const int order = d0 <= d1;
3147
3148
151k
                static const uint8_t quant_dist_weight[3][2] = {
3149
151k
                    { 2, 3 }, { 2, 5 }, { 2, 7 }
3150
151k
                };
3151
151k
                static const uint8_t quant_dist_lookup_table[4][2] = {
3152
151k
                    { 9, 7 }, { 11, 5 }, { 12, 4 }, { 13, 3 }
3153
151k
                };
3154
3155
151k
                int k;
3156
441k
                for (k = 0; k < 3; k++) {
3157
346k
                    const int c0 = quant_dist_weight[k][order];
3158
346k
                    const int c1 = quant_dist_weight[k][!order];
3159
346k
                    const int d0_c0 = d0 * c0;
3160
346k
                    const int d1_c1 = d1 * c1;
3161
346k
                    if ((d0 > d1 && d0_c0 < d1_c1) || (d0 <= d1 && d0_c0 > d1_c1)) break;
3162
346k
                }
3163
3164
151k
                f->jnt_weights[i][j] = quant_dist_lookup_table[k][order];
3165
151k
            }
3166
50.5k
        }
3167
7.22k
    }
3168
3169
    /* Init loopfilter pointers. Increasing NULL pointers is technically UB,
3170
     * so just point the chroma pointers in 4:0:0 to the luma plane here to
3171
     * avoid having additional in-loop branches in various places. We never
3172
     * dereference those pointers so it doesn't really matter what they
3173
     * point at, as long as the pointers are valid. */
3174
28.4k
    const int has_chroma = f->cur.p.layout != DAV1D_PIXEL_LAYOUT_I400;
3175
28.4k
    f->lf.p[0] = f->cur.data[0];
3176
28.4k
    f->lf.p[1] = f->cur.data[has_chroma ? 1 : 0];
3177
28.4k
    f->lf.p[2] = f->cur.data[has_chroma ? 2 : 0];
3178
28.4k
    f->lf.sr_p[0] = f->sr_cur.p.data[0];
3179
28.4k
    f->lf.sr_p[1] = f->sr_cur.p.data[has_chroma ? 1 : 0];
3180
28.4k
    f->lf.sr_p[2] = f->sr_cur.p.data[has_chroma ? 2 : 0];
3181
3182
28.4k
    retval = 0;
3183
28.4k
error:
3184
28.4k
    return retval;
3185
28.4k
}
3186
3187
27.5k
int dav1d_decode_frame_init_cdf(Dav1dFrameContext *const f) {
3188
27.5k
    const Dav1dContext *const c = f->c;
3189
27.5k
    int retval = DAV1D_ERR(EINVAL);
3190
3191
27.5k
    if (f->frame_hdr->refresh_context)
3192
10.7k
        dav1d_cdf_thread_copy(f->out_cdf.data.cdf, &f->in_cdf);
3193
3194
    // parse individual tiles per tile group
3195
27.5k
    int tile_row = 0, tile_col = 0;
3196
27.5k
    f->task_thread.update_set = 0;
3197
54.7k
    for (int i = 0; i < f->n_tile_data; i++) {
3198
27.5k
        const uint8_t *data = f->tile[i].data.data;
3199
27.5k
        size_t size = f->tile[i].data.sz;
3200
3201
59.0k
        for (int j = f->tile[i].start; j <= f->tile[i].end; j++) {
3202
31.8k
            size_t tile_sz;
3203
31.8k
            if (j == f->tile[i].end) {
3204
27.1k
                tile_sz = size;
3205
27.1k
            } else {
3206
4.63k
                if (f->frame_hdr->tiling.n_bytes > size) goto error;
3207
4.57k
                tile_sz = 0;
3208
10.2k
                for (unsigned k = 0; k < f->frame_hdr->tiling.n_bytes; k++)
3209
5.70k
                    tile_sz |= (unsigned)*data++ << (k * 8);
3210
4.57k
                tile_sz++;
3211
4.57k
                size -= f->frame_hdr->tiling.n_bytes;
3212
4.57k
                if (tile_sz > size) goto error;
3213
4.57k
            }
3214
3215
31.5k
            setup_tile(&f->ts[j], f, data, tile_sz, tile_row, tile_col++,
3216
18.4E
                       c->n_fc > 1 ? f->frame_thread.tile_start_off[j] : 0);
3217
3218
31.5k
            if (tile_col == f->frame_hdr->tiling.cols) {
3219
29.2k
                tile_col = 0;
3220
29.2k
                tile_row++;
3221
29.2k
            }
3222
31.5k
            if (j == f->frame_hdr->tiling.update && f->frame_hdr->refresh_context)
3223
10.6k
                f->task_thread.update_set = 1;
3224
31.5k
            data += tile_sz;
3225
31.5k
            size -= tile_sz;
3226
31.5k
        }
3227
27.5k
    }
3228
3229
27.1k
    if (c->n_tc > 1) {
3230
27.1k
        const int uses_2pass = c->n_fc > 1;
3231
222k
        for (int n = 0; n < f->sb128w * f->frame_hdr->tiling.rows * (1 + uses_2pass); n++)
3232
195k
            reset_context(&f->a[n], IS_KEY_OR_INTRA(f->frame_hdr),
3233
18.4E
                          uses_2pass ? 1 + (n >= f->sb128w * f->frame_hdr->tiling.rows) : 0);
3234
27.1k
    }
3235
3236
27.1k
    retval = 0;
3237
27.5k
error:
3238
27.5k
    return retval;
3239
27.1k
}
3240
3241
0
int dav1d_decode_frame_main(Dav1dFrameContext *const f) {
3242
0
    const Dav1dContext *const c = f->c;
3243
0
    int retval = DAV1D_ERR(EINVAL);
3244
3245
0
    assert(f->c->n_tc == 1);
3246
3247
0
    Dav1dTaskContext *const t = &c->tc[f - c->fc];
3248
0
    t->f = f;
3249
0
    t->frame_thread.pass = 0;
3250
3251
0
    for (int n = 0; n < f->sb128w * f->frame_hdr->tiling.rows; n++)
3252
0
        reset_context(&f->a[n], IS_KEY_OR_INTRA(f->frame_hdr), 0);
3253
3254
    // no threading - we explicitly interleave tile/sbrow decoding
3255
    // and post-filtering, so that the full process runs in-line
3256
0
    for (int tile_row = 0; tile_row < f->frame_hdr->tiling.rows; tile_row++) {
3257
0
        const int sbh_end =
3258
0
            imin(f->frame_hdr->tiling.row_start_sb[tile_row + 1], f->sbh);
3259
0
        for (int sby = f->frame_hdr->tiling.row_start_sb[tile_row];
3260
0
             sby < sbh_end; sby++)
3261
0
        {
3262
0
            t->by = sby << (4 + f->seq_hdr->sb128);
3263
0
            const int by_end = (t->by + f->sb_step) >> 1;
3264
0
            if (f->frame_hdr->use_ref_frame_mvs) {
3265
0
                f->c->refmvs_dsp.load_tmvs(&f->rf, tile_row,
3266
0
                                           0, f->bw >> 1, t->by >> 1, by_end);
3267
0
            }
3268
0
            for (int tile_col = 0; tile_col < f->frame_hdr->tiling.cols; tile_col++) {
3269
0
                t->ts = &f->ts[tile_row * f->frame_hdr->tiling.cols + tile_col];
3270
0
                if (dav1d_decode_tile_sbrow(t)) goto error;
3271
0
            }
3272
0
            if (IS_INTER_OR_SWITCH(f->frame_hdr)) {
3273
0
                dav1d_refmvs_save_tmvs(&f->c->refmvs_dsp, &t->rt,
3274
0
                                       0, f->bw >> 1, t->by >> 1, by_end);
3275
0
            }
3276
3277
            // loopfilter + cdef + restoration
3278
0
            f->bd_fn.filter_sbrow(f, sby);
3279
0
        }
3280
0
    }
3281
3282
0
    retval = 0;
3283
0
error:
3284
0
    return retval;
3285
0
}
3286
3287
131k
void dav1d_decode_frame_exit(Dav1dFrameContext *const f, int retval) {
3288
131k
    const Dav1dContext *const c = f->c;
3289
3290
131k
    if (f->sr_cur.p.data[0])
3291
131k
        atomic_init(&f->task_thread.error, 0);
3292
3293
131k
    if (c->n_fc > 1 && retval && f->frame_thread.cf) {
3294
33.9k
        memset(f->frame_thread.cf, 0,
3295
33.9k
               (size_t)f->frame_thread.cf_sz * 128 * 128 / 2);
3296
33.9k
    }
3297
1.04M
    for (int i = 0; i < 7; i++) {
3298
917k
        if (f->refp[i].p.frame_hdr) {
3299
81.4k
            if (!retval && c->n_fc > 1 && c->strict_std_compliance &&
3300
81.4k
                atomic_load(&f->refp[i].progress[1]) == FRAME_ERROR)
3301
0
            {
3302
0
                retval = DAV1D_ERR(EINVAL);
3303
0
                atomic_store(&f->task_thread.error, 1);
3304
0
                atomic_store(&f->sr_cur.progress[1], FRAME_ERROR);
3305
0
            }
3306
81.4k
            dav1d_thread_picture_unref(&f->refp[i]);
3307
81.4k
        }
3308
917k
        dav1d_ref_dec(&f->ref_mvs_ref[i]);
3309
917k
    }
3310
3311
131k
    dav1d_picture_unref_internal(&f->cur);
3312
131k
    dav1d_thread_picture_unref(&f->sr_cur);
3313
131k
    dav1d_cdf_thread_unref(&f->in_cdf);
3314
131k
    if (f->frame_hdr && f->frame_hdr->refresh_context) {
3315
23.0k
        if (f->out_cdf.progress)
3316
23.0k
            atomic_store(f->out_cdf.progress, retval == 0 ? 1 : TILE_ERROR);
3317
23.0k
        dav1d_cdf_thread_unref(&f->out_cdf);
3318
23.0k
    }
3319
131k
    dav1d_ref_dec(&f->cur_segmap_ref);
3320
131k
    dav1d_ref_dec(&f->prev_segmap_ref);
3321
131k
    dav1d_ref_dec(&f->mvs_ref);
3322
131k
    dav1d_ref_dec(&f->seq_hdr_ref);
3323
131k
    dav1d_ref_dec(&f->frame_hdr_ref);
3324
3325
160k
    for (int i = 0; i < f->n_tile_data; i++)
3326
29.5k
        dav1d_data_unref_internal(&f->tile[i].data);
3327
131k
    f->task_thread.retval = retval;
3328
131k
}
3329
3330
0
int dav1d_decode_frame(Dav1dFrameContext *const f) {
3331
0
    assert(f->c->n_fc == 1);
3332
    // if n_tc > 1 (but n_fc == 1), we could run init/exit in the task
3333
    // threads also. Not sure it makes a measurable difference.
3334
0
    int res = dav1d_decode_frame_init(f);
3335
0
    if (!res) res = dav1d_decode_frame_init_cdf(f);
3336
    // wait until all threads have completed
3337
0
    if (!res) {
3338
0
        if (f->c->n_tc > 1) {
3339
0
            res = dav1d_task_create_tile_sbrow(f, 0, 1);
3340
0
            pthread_mutex_lock(&f->task_thread.ttd->lock);
3341
0
            pthread_cond_signal(&f->task_thread.ttd->cond);
3342
0
            if (!res) {
3343
0
                while (!f->task_thread.done[0] ||
3344
0
                       atomic_load(&f->task_thread.task_counter) > 0)
3345
0
                {
3346
0
                    pthread_cond_wait(&f->task_thread.cond,
3347
0
                                      &f->task_thread.ttd->lock);
3348
0
                }
3349
0
            }
3350
0
            pthread_mutex_unlock(&f->task_thread.ttd->lock);
3351
0
            res = f->task_thread.retval;
3352
0
        } else {
3353
0
            res = dav1d_decode_frame_main(f);
3354
0
            if (!res && f->frame_hdr->refresh_context && f->task_thread.update_set) {
3355
0
                dav1d_cdf_thread_update(f->frame_hdr, f->out_cdf.data.cdf,
3356
0
                                        &f->ts[f->frame_hdr->tiling.update].cdf);
3357
0
            }
3358
0
        }
3359
0
    }
3360
0
    dav1d_decode_frame_exit(f, res);
3361
0
    res = f->task_thread.retval;
3362
0
    f->n_tile_data = 0;
3363
0
    return res;
3364
0
}
3365
3366
11.9k
static int get_upscale_x0(const int in_w, const int out_w, const int step) {
3367
11.9k
    const int err = out_w * step - (in_w << 14);
3368
11.9k
    const int x0 = (-((out_w - in_w) << 13) + (out_w >> 1)) / out_w + 128 - (err / 2);
3369
11.9k
    return x0 & 0x3fff;
3370
11.9k
}
3371
3372
29.6k
int dav1d_submit_frame(Dav1dContext *const c) {
3373
29.6k
    Dav1dFrameContext *f;
3374
29.6k
    int res = -1;
3375
3376
    // wait for c->out_delayed[next] and move into c->out if visible
3377
29.6k
    Dav1dThreadPicture *out_delayed;
3378
29.6k
    if (c->n_fc > 1) {
3379
29.6k
        pthread_mutex_lock(&c->task_thread.lock);
3380
29.6k
        const unsigned next = c->frame_thread.next++;
3381
29.6k
        if (c->frame_thread.next == c->n_fc)
3382
851
            c->frame_thread.next = 0;
3383
3384
29.6k
        f = &c->fc[next];
3385
29.7k
        while (f->n_tile_data > 0)
3386
90
            pthread_cond_wait(&f->task_thread.cond,
3387
90
                              &c->task_thread.lock);
3388
29.6k
        out_delayed = &c->frame_thread.out_delayed[next];
3389
29.6k
        if (out_delayed->p.data[0] || atomic_load(&f->task_thread.error)) {
3390
104
            unsigned first = atomic_load(&c->task_thread.first);
3391
104
            if (first + 1U < c->n_fc)
3392
104
                atomic_fetch_add(&c->task_thread.first, 1U);
3393
0
            else
3394
104
                atomic_store(&c->task_thread.first, 0);
3395
104
            atomic_compare_exchange_strong(&c->task_thread.reset_task_cur,
3396
104
                                           &first, UINT_MAX);
3397
104
            if (c->task_thread.cur && c->task_thread.cur < c->n_fc)
3398
21
                c->task_thread.cur--;
3399
104
        }
3400
29.6k
        const int error = f->task_thread.retval;
3401
29.6k
        if (error) {
3402
0
            f->task_thread.retval = 0;
3403
0
            c->cached_error = error;
3404
0
            dav1d_data_props_copy(&c->cached_error_props, &out_delayed->p.m);
3405
0
            dav1d_thread_picture_unref(out_delayed);
3406
29.6k
        } else if (out_delayed->p.data[0]) {
3407
104
            const unsigned progress = atomic_load_explicit(&out_delayed->progress[1],
3408
104
                                                           memory_order_relaxed);
3409
104
            if ((out_delayed->visible || c->output_invisible_frames) &&
3410
104
                progress != FRAME_ERROR)
3411
104
            {
3412
104
                dav1d_thread_picture_ref(&c->out, out_delayed);
3413
104
                c->event_flags |= dav1d_picture_get_event_flags(out_delayed);
3414
104
            }
3415
104
            dav1d_thread_picture_unref(out_delayed);
3416
104
        }
3417
29.6k
    } else {
3418
0
        f = c->fc;
3419
0
    }
3420
3421
29.6k
    f->seq_hdr = c->seq_hdr;
3422
29.6k
    f->seq_hdr_ref = c->seq_hdr_ref;
3423
29.6k
    dav1d_ref_inc(f->seq_hdr_ref);
3424
29.6k
    f->frame_hdr = c->frame_hdr;
3425
29.6k
    f->frame_hdr_ref = c->frame_hdr_ref;
3426
29.6k
    c->frame_hdr = NULL;
3427
29.6k
    c->frame_hdr_ref = NULL;
3428
29.6k
    f->dsp = &c->dsp[f->seq_hdr->hbd];
3429
3430
29.6k
    const int bpc = 8 + 2 * f->seq_hdr->hbd;
3431
3432
29.6k
    if (!f->dsp->ipred.intra_pred[DC_PRED]) {
3433
16.6k
        Dav1dDSPContext *const dsp = &c->dsp[f->seq_hdr->hbd];
3434
3435
16.6k
        switch (bpc) {
3436
0
#define assign_bitdepth_case(bd) \
3437
16.6k
            dav1d_cdef_dsp_init_##bd##bpc(&dsp->cdef); \
3438
16.6k
            dav1d_intra_pred_dsp_init_##bd##bpc(&dsp->ipred); \
3439
16.6k
            dav1d_itx_dsp_init_##bd##bpc(&dsp->itx, bpc); \
3440
16.6k
            dav1d_loop_filter_dsp_init_##bd##bpc(&dsp->lf); \
3441
16.6k
            dav1d_loop_restoration_dsp_init_##bd##bpc(&dsp->lr, bpc); \
3442
16.6k
            dav1d_mc_dsp_init_##bd##bpc(&dsp->mc); \
3443
16.6k
            dav1d_film_grain_dsp_init_##bd##bpc(&dsp->fg); \
3444
16.6k
            break
3445
0
#if CONFIG_8BPC
3446
8.14k
        case 8:
3447
8.14k
            assign_bitdepth_case(8);
3448
0
#endif
3449
0
#if CONFIG_16BPC
3450
7.13k
        case 10:
3451
8.49k
        case 12:
3452
8.49k
            assign_bitdepth_case(16);
3453
0
#endif
3454
0
#undef assign_bitdepth_case
3455
0
        default:
3456
0
            dav1d_log(c, "Compiled without support for %d-bit decoding\n",
3457
0
                    8 + 2 * f->seq_hdr->hbd);
3458
0
            res = DAV1D_ERR(ENOPROTOOPT);
3459
0
            goto error;
3460
16.6k
        }
3461
16.6k
    }
3462
3463
29.6k
#define assign_bitdepth_case(bd) \
3464
29.6k
        f->bd_fn.recon_b_inter = dav1d_recon_b_inter_##bd##bpc; \
3465
29.6k
        f->bd_fn.recon_b_intra = dav1d_recon_b_intra_##bd##bpc; \
3466
29.6k
        f->bd_fn.filter_sbrow = dav1d_filter_sbrow_##bd##bpc; \
3467
29.6k
        f->bd_fn.filter_sbrow_deblock_cols = dav1d_filter_sbrow_deblock_cols_##bd##bpc; \
3468
29.6k
        f->bd_fn.filter_sbrow_deblock_rows = dav1d_filter_sbrow_deblock_rows_##bd##bpc; \
3469
29.6k
        f->bd_fn.filter_sbrow_cdef = dav1d_filter_sbrow_cdef_##bd##bpc; \
3470
29.6k
        f->bd_fn.filter_sbrow_resize = dav1d_filter_sbrow_resize_##bd##bpc; \
3471
29.6k
        f->bd_fn.filter_sbrow_lr = dav1d_filter_sbrow_lr_##bd##bpc; \
3472
29.6k
        f->bd_fn.backup_ipred_edge = dav1d_backup_ipred_edge_##bd##bpc; \
3473
29.6k
        f->bd_fn.read_coef_blocks = dav1d_read_coef_blocks_##bd##bpc; \
3474
29.6k
        f->bd_fn.copy_pal_block_y = dav1d_copy_pal_block_y_##bd##bpc; \
3475
29.6k
        f->bd_fn.copy_pal_block_uv = dav1d_copy_pal_block_uv_##bd##bpc; \
3476
29.6k
        f->bd_fn.read_pal_plane = dav1d_read_pal_plane_##bd##bpc; \
3477
29.6k
        f->bd_fn.read_pal_uv = dav1d_read_pal_uv_##bd##bpc
3478
29.6k
    if (!f->seq_hdr->hbd) {
3479
15.5k
#if CONFIG_8BPC
3480
15.5k
        assign_bitdepth_case(8);
3481
15.5k
#endif
3482
15.5k
    } else {
3483
14.0k
#if CONFIG_16BPC
3484
14.0k
        assign_bitdepth_case(16);
3485
14.0k
#endif
3486
14.0k
    }
3487
29.6k
#undef assign_bitdepth_case
3488
3489
29.6k
    int ref_coded_width[7];
3490
29.6k
    if (IS_INTER_OR_SWITCH(f->frame_hdr)) {
3491
11.7k
        if (f->frame_hdr->primary_ref_frame != DAV1D_PRIMARY_REF_NONE) {
3492
10.0k
            const int pri_ref = f->frame_hdr->refidx[f->frame_hdr->primary_ref_frame];
3493
10.0k
            if (!c->refs[pri_ref].p.p.data[0]) {
3494
4
                res = DAV1D_ERR(EINVAL);
3495
4
                goto error;
3496
4
            }
3497
10.0k
        }
3498
93.2k
        for (int i = 0; i < 7; i++) {
3499
81.6k
            const int refidx = f->frame_hdr->refidx[i];
3500
81.6k
            if (!c->refs[refidx].p.p.data[0] ||
3501
81.5k
                f->frame_hdr->width[0] * 2 < c->refs[refidx].p.p.p.w ||
3502
81.5k
                f->frame_hdr->height * 2 < c->refs[refidx].p.p.p.h ||
3503
81.5k
                f->frame_hdr->width[0] > c->refs[refidx].p.p.p.w * 16 ||
3504
81.5k
                f->frame_hdr->height > c->refs[refidx].p.p.p.h * 16 ||
3505
81.5k
                f->seq_hdr->layout != c->refs[refidx].p.p.p.layout ||
3506
81.5k
                bpc != c->refs[refidx].p.p.p.bpc)
3507
106
            {
3508
184
                for (int j = 0; j < i; j++)
3509
78
                    dav1d_thread_picture_unref(&f->refp[j]);
3510
106
                res = DAV1D_ERR(EINVAL);
3511
106
                goto error;
3512
106
            }
3513
81.5k
            dav1d_thread_picture_ref(&f->refp[i], &c->refs[refidx].p);
3514
81.5k
            ref_coded_width[i] = c->refs[refidx].p.p.frame_hdr->width[0];
3515
81.5k
            if (f->frame_hdr->width[0] != c->refs[refidx].p.p.p.w ||
3516
53.9k
                f->frame_hdr->height != c->refs[refidx].p.p.p.h)
3517
30.5k
            {
3518
30.5k
#define scale_fac(ref_sz, this_sz) \
3519
72.9k
    ((((ref_sz) << 14) + ((this_sz) >> 1)) / (this_sz))
3520
30.5k
                f->svc[i][0].scale = scale_fac(c->refs[refidx].p.p.p.w,
3521
30.5k
                                               f->frame_hdr->width[0]);
3522
30.5k
                f->svc[i][1].scale = scale_fac(c->refs[refidx].p.p.p.h,
3523
30.5k
                                               f->frame_hdr->height);
3524
30.5k
                f->svc[i][0].step = (f->svc[i][0].scale + 8) >> 4;
3525
30.5k
                f->svc[i][1].step = (f->svc[i][1].scale + 8) >> 4;
3526
50.9k
            } else {
3527
50.9k
                f->svc[i][0].scale = f->svc[i][1].scale = 0;
3528
50.9k
            }
3529
81.5k
            f->gmv_warp_allowed[i] = f->frame_hdr->gmv[i].type > DAV1D_WM_TYPE_TRANSLATION &&
3530
22.3k
                                     !f->frame_hdr->force_integer_mv &&
3531
17.4k
                                     !dav1d_get_shear_params(&f->frame_hdr->gmv[i]) &&
3532
16.2k
                                     !f->svc[i][0].scale;
3533
81.5k
        }
3534
11.7k
    }
3535
3536
    // setup entropy
3537
29.5k
    if (f->frame_hdr->primary_ref_frame == DAV1D_PRIMARY_REF_NONE) {
3538
19.5k
        dav1d_cdf_thread_init_static(&f->in_cdf, f->frame_hdr->quant.yac);
3539
19.5k
    } else {
3540
9.97k
        const int pri_ref = f->frame_hdr->refidx[f->frame_hdr->primary_ref_frame];
3541
9.97k
        dav1d_cdf_thread_ref(&f->in_cdf, &c->cdf[pri_ref]);
3542
9.97k
    }
3543
29.5k
    if (f->frame_hdr->refresh_context) {
3544
11.9k
        res = dav1d_cdf_thread_alloc(c, &f->out_cdf, c->n_fc > 1);
3545
11.9k
        if (res < 0) goto error;
3546
11.9k
    }
3547
3548
    // FIXME qsort so tiles are in order (for frame threading)
3549
29.5k
    if (f->n_tile_data_alloc < c->n_tile_data) {
3550
29.4k
        dav1d_free(f->tile);
3551
29.4k
        assert(c->n_tile_data < INT_MAX / (int)sizeof(*f->tile));
3552
29.4k
        f->tile = dav1d_malloc(ALLOC_TILE, c->n_tile_data * sizeof(*f->tile));
3553
29.4k
        if (!f->tile) {
3554
0
            f->n_tile_data_alloc = f->n_tile_data = 0;
3555
0
            res = DAV1D_ERR(ENOMEM);
3556
0
            goto error;
3557
0
        }
3558
29.4k
        f->n_tile_data_alloc = c->n_tile_data;
3559
29.4k
    }
3560
29.5k
    memcpy(f->tile, c->tile, c->n_tile_data * sizeof(*f->tile));
3561
29.5k
    memset(c->tile, 0, c->n_tile_data * sizeof(*c->tile));
3562
29.5k
    f->n_tile_data = c->n_tile_data;
3563
29.5k
    c->n_tile_data = 0;
3564
3565
    // allocate frame
3566
29.5k
    res = dav1d_thread_picture_alloc(c, f, bpc);
3567
29.5k
    if (res < 0) goto error;
3568
3569
29.5k
    if (f->frame_hdr->width[0] != f->frame_hdr->width[1]) {
3570
5.95k
        res = dav1d_picture_alloc_copy(c, &f->cur, f->frame_hdr->width[0], &f->sr_cur.p);
3571
5.95k
        if (res < 0) goto error;
3572
23.5k
    } else {
3573
23.5k
        dav1d_picture_ref(&f->cur, &f->sr_cur.p);
3574
23.5k
    }
3575
3576
29.5k
    if (f->frame_hdr->width[0] != f->frame_hdr->width[1]) {
3577
5.95k
        f->resize_step[0] = scale_fac(f->cur.p.w, f->sr_cur.p.p.w);
3578
5.95k
        const int ss_hor = f->cur.p.layout != DAV1D_PIXEL_LAYOUT_I444;
3579
5.95k
        const int in_cw = (f->cur.p.w + ss_hor) >> ss_hor;
3580
5.95k
        const int out_cw = (f->sr_cur.p.p.w + ss_hor) >> ss_hor;
3581
5.95k
        f->resize_step[1] = scale_fac(in_cw, out_cw);
3582
5.95k
#undef scale_fac
3583
5.95k
        f->resize_start[0] = get_upscale_x0(f->cur.p.w, f->sr_cur.p.p.w, f->resize_step[0]);
3584
5.95k
        f->resize_start[1] = get_upscale_x0(in_cw, out_cw, f->resize_step[1]);
3585
5.95k
    }
3586
3587
    // move f->cur into output queue
3588
29.5k
    if (c->n_fc == 1) {
3589
0
        if (f->frame_hdr->show_frame || c->output_invisible_frames) {
3590
0
            dav1d_thread_picture_ref(&c->out, &f->sr_cur);
3591
0
            c->event_flags |= dav1d_picture_get_event_flags(&f->sr_cur);
3592
0
        }
3593
29.5k
    } else {
3594
29.5k
        dav1d_thread_picture_ref(out_delayed, &f->sr_cur);
3595
29.5k
    }
3596
3597
29.5k
    f->w4 = (f->frame_hdr->width[0] + 3) >> 2;
3598
29.5k
    f->h4 = (f->frame_hdr->height + 3) >> 2;
3599
29.5k
    f->bw = ((f->frame_hdr->width[0] + 7) >> 3) << 1;
3600
29.5k
    f->bh = ((f->frame_hdr->height + 7) >> 3) << 1;
3601
29.5k
    f->sb128w = (f->bw + 31) >> 5;
3602
29.5k
    f->sb128h = (f->bh + 31) >> 5;
3603
29.5k
    f->sb_shift = 4 + f->seq_hdr->sb128;
3604
29.5k
    f->sb_step = 16 << f->seq_hdr->sb128;
3605
29.5k
    f->sbh = (f->bh + f->sb_step - 1) >> f->sb_shift;
3606
29.5k
    f->b4_stride = (f->bw + 31) & ~31;
3607
29.5k
    f->bitdepth_max = (1 << f->cur.p.bpc) - 1;
3608
29.5k
    atomic_init(&f->task_thread.error, 0);
3609
29.5k
    const int uses_2pass = c->n_fc > 1;
3610
29.5k
    const int cols = f->frame_hdr->tiling.cols;
3611
29.5k
    const int rows = f->frame_hdr->tiling.rows;
3612
29.5k
    atomic_store(&f->task_thread.task_counter,
3613
29.5k
                 (cols * rows + f->sbh) << uses_2pass);
3614
3615
    // ref_mvs
3616
29.5k
    if (IS_INTER_OR_SWITCH(f->frame_hdr) || f->frame_hdr->allow_intrabc) {
3617
15.0k
        f->mvs_ref = dav1d_ref_create_using_pool(c->refmvs_pool,
3618
15.0k
            sizeof(*f->mvs) * f->sb128h * 16 * (f->b4_stride >> 1));
3619
15.0k
        if (!f->mvs_ref) {
3620
0
            res = DAV1D_ERR(ENOMEM);
3621
0
            goto error;
3622
0
        }
3623
15.0k
        f->mvs = f->mvs_ref->data;
3624
15.0k
        if (!f->frame_hdr->allow_intrabc) {
3625
93.0k
            for (int i = 0; i < 7; i++)
3626
81.4k
                f->refpoc[i] = f->refp[i].p.frame_hdr->frame_offset;
3627
11.6k
        } else {
3628
3.44k
            memset(f->refpoc, 0, sizeof(f->refpoc));
3629
3.44k
        }
3630
15.0k
        if (f->frame_hdr->use_ref_frame_mvs) {
3631
19.7k
            for (int i = 0; i < 7; i++) {
3632
17.2k
                const int refidx = f->frame_hdr->refidx[i];
3633
17.2k
                const int ref_w = ((ref_coded_width[i] + 7) >> 3) << 1;
3634
17.2k
                const int ref_h = ((f->refp[i].p.p.h + 7) >> 3) << 1;
3635
17.2k
                if (c->refs[refidx].refmvs != NULL &&
3636
4.38k
                    ref_w == f->bw && ref_h == f->bh)
3637
3.83k
                {
3638
3.83k
                    f->ref_mvs_ref[i] = c->refs[refidx].refmvs;
3639
3.83k
                    dav1d_ref_inc(f->ref_mvs_ref[i]);
3640
3.83k
                    f->ref_mvs[i] = c->refs[refidx].refmvs->data;
3641
13.4k
                } else {
3642
13.4k
                    f->ref_mvs[i] = NULL;
3643
13.4k
                    f->ref_mvs_ref[i] = NULL;
3644
13.4k
                }
3645
17.2k
                memcpy(f->refrefpoc[i], c->refs[refidx].refpoc,
3646
17.2k
                       sizeof(*f->refrefpoc));
3647
17.2k
            }
3648
12.6k
        } else {
3649
12.6k
            memset(f->ref_mvs_ref, 0, sizeof(f->ref_mvs_ref));
3650
12.6k
        }
3651
15.0k
    } else {
3652
14.4k
        f->mvs_ref = NULL;
3653
14.4k
        memset(f->ref_mvs_ref, 0, sizeof(f->ref_mvs_ref));
3654
14.4k
    }
3655
3656
    // segmap
3657
29.5k
    if (f->frame_hdr->segmentation.enabled) {
3658
        // By default, the previous segmentation map is not initialised.
3659
14.2k
        f->prev_segmap_ref = NULL;
3660
14.2k
        f->prev_segmap = NULL;
3661
3662
        // We might need a previous frame's segmentation map. This
3663
        // happens if there is either no update or a temporal update.
3664
14.2k
        if (f->frame_hdr->segmentation.temporal || !f->frame_hdr->segmentation.update_map) {
3665
4.00k
            const int pri_ref = f->frame_hdr->primary_ref_frame;
3666
4.00k
            assert(pri_ref != DAV1D_PRIMARY_REF_NONE);
3667
4.00k
            const int ref_w = ((ref_coded_width[pri_ref] + 7) >> 3) << 1;
3668
4.00k
            const int ref_h = ((f->refp[pri_ref].p.p.h + 7) >> 3) << 1;
3669
4.00k
            if (ref_w == f->bw && ref_h == f->bh) {
3670
3.07k
                f->prev_segmap_ref = c->refs[f->frame_hdr->refidx[pri_ref]].segmap;
3671
3.07k
                if (f->prev_segmap_ref) {
3672
2.43k
                    dav1d_ref_inc(f->prev_segmap_ref);
3673
2.43k
                    f->prev_segmap = f->prev_segmap_ref->data;
3674
2.43k
                }
3675
3.07k
            }
3676
4.00k
        }
3677
3678
14.2k
        if (f->frame_hdr->segmentation.update_map) {
3679
            // We're updating an existing map, but need somewhere to
3680
            // put the new values. Allocate them here (the data
3681
            // actually gets set elsewhere)
3682
10.6k
            f->cur_segmap_ref = dav1d_ref_create_using_pool(c->segmap_pool,
3683
10.6k
                sizeof(*f->cur_segmap) * f->b4_stride * 32 * f->sb128h);
3684
10.6k
            if (!f->cur_segmap_ref) {
3685
0
                dav1d_ref_dec(&f->prev_segmap_ref);
3686
0
                res = DAV1D_ERR(ENOMEM);
3687
0
                goto error;
3688
0
            }
3689
10.6k
            f->cur_segmap = f->cur_segmap_ref->data;
3690
10.6k
        } else if (f->prev_segmap_ref) {
3691
            // We're not updating an existing map, and we have a valid
3692
            // reference. Use that.
3693
2.21k
            f->cur_segmap_ref = f->prev_segmap_ref;
3694
2.21k
            dav1d_ref_inc(f->cur_segmap_ref);
3695
2.21k
            f->cur_segmap = f->prev_segmap_ref->data;
3696
2.21k
        } else {
3697
            // We need to make a new map. Allocate one here and zero it out.
3698
1.31k
            const size_t segmap_size = sizeof(*f->cur_segmap) * f->b4_stride * 32 * f->sb128h;
3699
1.31k
            f->cur_segmap_ref = dav1d_ref_create_using_pool(c->segmap_pool, segmap_size);
3700
1.31k
            if (!f->cur_segmap_ref) {
3701
0
                res = DAV1D_ERR(ENOMEM);
3702
0
                goto error;
3703
0
            }
3704
1.31k
            f->cur_segmap = f->cur_segmap_ref->data;
3705
1.31k
            memset(f->cur_segmap, 0, segmap_size);
3706
1.31k
        }
3707
15.2k
    } else {
3708
15.2k
        f->cur_segmap = NULL;
3709
15.2k
        f->cur_segmap_ref = NULL;
3710
15.2k
        f->prev_segmap_ref = NULL;
3711
15.2k
    }
3712
3713
    // update references etc.
3714
29.5k
    const unsigned refresh_frame_flags = f->frame_hdr->refresh_frame_flags;
3715
265k
    for (int i = 0; i < 8; i++) {
3716
236k
        if (refresh_frame_flags & (1 << i)) {
3717
179k
            if (c->refs[i].p.p.frame_hdr)
3718
54.6k
                dav1d_thread_picture_unref(&c->refs[i].p);
3719
179k
            dav1d_thread_picture_ref(&c->refs[i].p, &f->sr_cur);
3720
3721
179k
            dav1d_cdf_thread_unref(&c->cdf[i]);
3722
179k
            if (f->frame_hdr->refresh_context) {
3723
61.7k
                dav1d_cdf_thread_ref(&c->cdf[i], &f->out_cdf);
3724
117k
            } else {
3725
117k
                dav1d_cdf_thread_ref(&c->cdf[i], &f->in_cdf);
3726
117k
            }
3727
3728
179k
            dav1d_ref_dec(&c->refs[i].segmap);
3729
179k
            c->refs[i].segmap = f->cur_segmap_ref;
3730
179k
            if (f->cur_segmap_ref)
3731
85.2k
                dav1d_ref_inc(f->cur_segmap_ref);
3732
179k
            dav1d_ref_dec(&c->refs[i].refmvs);
3733
179k
            if (!f->frame_hdr->allow_intrabc) {
3734
153k
                c->refs[i].refmvs = f->mvs_ref;
3735
153k
                if (f->mvs_ref)
3736
48.9k
                    dav1d_ref_inc(f->mvs_ref);
3737
153k
            }
3738
179k
            memcpy(c->refs[i].refpoc, f->refpoc, sizeof(f->refpoc));
3739
179k
        }
3740
236k
    }
3741
3742
29.5k
    if (c->n_fc == 1) {
3743
0
        if ((res = dav1d_decode_frame(f)) < 0) {
3744
0
            dav1d_thread_picture_unref(&c->out);
3745
0
            for (int i = 0; i < 8; i++) {
3746
0
                if (refresh_frame_flags & (1 << i)) {
3747
0
                    if (c->refs[i].p.p.frame_hdr)
3748
0
                        dav1d_thread_picture_unref(&c->refs[i].p);
3749
0
                    dav1d_cdf_thread_unref(&c->cdf[i]);
3750
0
                    dav1d_ref_dec(&c->refs[i].segmap);
3751
0
                    dav1d_ref_dec(&c->refs[i].refmvs);
3752
0
                }
3753
0
            }
3754
0
            goto error;
3755
0
        }
3756
29.5k
    } else {
3757
29.5k
        dav1d_task_frame_init(f);
3758
29.5k
        pthread_mutex_unlock(&c->task_thread.lock);
3759
29.5k
    }
3760
3761
29.5k
    return 0;
3762
110
error:
3763
110
    atomic_init(&f->task_thread.error, 1);
3764
110
    dav1d_cdf_thread_unref(&f->in_cdf);
3765
110
    if (f->frame_hdr->refresh_context)
3766
58
        dav1d_cdf_thread_unref(&f->out_cdf);
3767
880
    for (int i = 0; i < 7; i++) {
3768
770
        if (f->refp[i].p.frame_hdr)
3769
0
            dav1d_thread_picture_unref(&f->refp[i]);
3770
770
        dav1d_ref_dec(&f->ref_mvs_ref[i]);
3771
770
    }
3772
110
    if (c->n_fc == 1)
3773
0
        dav1d_thread_picture_unref(&c->out);
3774
110
    else
3775
110
        dav1d_thread_picture_unref(out_delayed);
3776
110
    dav1d_picture_unref_internal(&f->cur);
3777
110
    dav1d_thread_picture_unref(&f->sr_cur);
3778
110
    dav1d_ref_dec(&f->mvs_ref);
3779
110
    dav1d_ref_dec(&f->seq_hdr_ref);
3780
110
    dav1d_ref_dec(&f->frame_hdr_ref);
3781
110
    dav1d_data_props_copy(&c->cached_error_props, &c->in.m);
3782
3783
110
    for (int i = 0; i < f->n_tile_data; i++)
3784
0
        dav1d_data_unref_internal(&f->tile[i].data);
3785
110
    f->n_tile_data = 0;
3786
3787
110
    if (c->n_fc > 1)
3788
110
        pthread_mutex_unlock(&c->task_thread.lock);
3789
3790
110
    return res;
3791
29.5k
}