Coverage Report

Created: 2026-10-28 06:18

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
159k
{
58
817k
    for (int i = 0; i < (frame_hdr->segmentation.enabled ? 8 : 1); i++) {
59
658k
        const int yac = frame_hdr->segmentation.enabled ?
60
570k
            iclip_u8(qidx + frame_hdr->segmentation.seg_data.d[i].delta_q) : qidx;
61
658k
        const int ydc = iclip_u8(yac + frame_hdr->quant.ydc_delta);
62
658k
        const int uac = iclip_u8(yac + frame_hdr->quant.uac_delta);
63
658k
        const int udc = iclip_u8(yac + frame_hdr->quant.udc_delta);
64
658k
        const int vac = iclip_u8(yac + frame_hdr->quant.vac_delta);
65
658k
        const int vdc = iclip_u8(yac + frame_hdr->quant.vdc_delta);
66
67
658k
        dq[i][0][0] = dav1d_dq_tbl[seq_hdr->hbd][ydc][0];
68
658k
        dq[i][0][1] = dav1d_dq_tbl[seq_hdr->hbd][yac][1];
69
658k
        dq[i][1][0] = dav1d_dq_tbl[seq_hdr->hbd][udc][0];
70
658k
        dq[i][1][1] = dav1d_dq_tbl[seq_hdr->hbd][uac][1];
71
658k
        dq[i][2][0] = dav1d_dq_tbl[seq_hdr->hbd][vdc][0];
72
658k
        dq[i][2][1] = dav1d_dq_tbl[seq_hdr->hbd][vac][1];
73
658k
    }
74
159k
}
75
76
static int read_mv_component_diff(MsacContext *const msac,
77
                                  CdfMvComponent *const mv_comp,
78
                                  const int mv_prec)
79
2.00M
{
80
2.00M
    const int sign = dav1d_msac_decode_bool_adapt(msac, mv_comp->sign);
81
2.00M
    const int cl = dav1d_msac_decode_symbol_adapt16(msac, mv_comp->classes, 10);
82
2.00M
    int up, fp = 3, hp = 1;
83
84
2.00M
    if (!cl) {
85
840k
        up = dav1d_msac_decode_bool_adapt(msac, mv_comp->class0);
86
840k
        if (mv_prec >= 0) {  // !force_integer_mv
87
246k
            fp = dav1d_msac_decode_symbol_adapt4(msac, mv_comp->class0_fp[up], 3);
88
246k
            if (mv_prec > 0) // allow_high_precision_mv
89
69.3k
                hp = dav1d_msac_decode_bool_adapt(msac, mv_comp->class0_hp);
90
246k
        }
91
1.16M
    } else {
92
1.16M
        up = 1 << cl;
93
11.7M
        for (int n = 0; n < cl; n++)
94
10.5M
            up |= dav1d_msac_decode_bool_adapt(msac, mv_comp->classN[n]) << n;
95
1.16M
        if (mv_prec >= 0) {  // !force_integer_mv
96
58.5k
            fp = dav1d_msac_decode_symbol_adapt4(msac, mv_comp->classN_fp, 3);
97
58.5k
            if (mv_prec > 0) // allow_high_precision_mv
98
16.6k
                hp = dav1d_msac_decode_bool_adapt(msac, mv_comp->classN_hp);
99
58.5k
        }
100
1.16M
    }
101
102
2.00M
    const int diff = ((up << 3) | (fp << 1) | hp) + 1;
103
104
2.00M
    return sign ? -diff : diff;
105
2.00M
}
106
107
static void read_mv_residual(Dav1dTileState *const ts, mv *const ref_mv,
108
                             const int mv_prec)
109
1.29M
{
110
1.29M
    MsacContext *const msac = &ts->msac;
111
1.29M
    const enum MVJoint mv_joint =
112
1.29M
        dav1d_msac_decode_symbol_adapt4(msac, ts->cdf.mv.joint, N_MV_JOINTS - 1);
113
1.29M
    if (mv_joint & MV_JOINT_V)
114
1.01M
        ref_mv->y += read_mv_component_diff(msac, &ts->cdf.mv.comp[0], mv_prec);
115
1.29M
    if (mv_joint & MV_JOINT_H)
116
997k
        ref_mv->x += read_mv_component_diff(msac, &ts->cdf.mv.comp[1], mv_prec);
117
1.29M
}
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
642k
{
124
642k
    const Dav1dFrameContext *const f = t->f;
125
642k
    const int bx4 = t->bx & 31, by4 = t->by & 31;
126
642k
    const TxfmInfo *const t_dim = &dav1d_txfm_dimensions[from];
127
642k
    const int txw = t_dim->lw, txh = t_dim->lh;
128
642k
    int is_split;
129
130
642k
    if (depth < 2 && from > (int) TX_4X4) {
131
553k
        const int cat = 2 * (TX_64X64 - t_dim->max) - depth;
132
553k
        const int a = t->a->tx[bx4] < txw;
133
553k
        const int l = t->l.tx[by4] < txh;
134
135
553k
        is_split = dav1d_msac_decode_bool_adapt(&t->ts->msac,
136
553k
                       t->ts->cdf.m.txpart[cat][a + l]);
137
553k
        if (is_split)
138
155k
            masks[depth] |= 1 << (y_off * 4 + x_off);
139
553k
    } else {
140
88.8k
        is_split = 0;
141
88.8k
    }
142
143
642k
    if (is_split && t_dim->max > TX_8X8) {
144
109k
        const enum RectTxfmSize sub = t_dim->sub;
145
109k
        const TxfmInfo *const sub_t_dim = &dav1d_txfm_dimensions[sub];
146
109k
        const int txsw = sub_t_dim->w, txsh = sub_t_dim->h;
147
148
109k
        read_tx_tree(t, sub, depth + 1, masks, x_off * 2 + 0, y_off * 2 + 0);
149
109k
        t->bx += txsw;
150
109k
        if (txw >= txh && t->bx < f->bw)
151
80.7k
            read_tx_tree(t, sub, depth + 1, masks, x_off * 2 + 1, y_off * 2 + 0);
152
109k
        t->bx -= txsw;
153
109k
        t->by += txsh;
154
109k
        if (txh >= txw && t->by < f->bh) {
155
67.0k
            read_tx_tree(t, sub, depth + 1, masks, x_off * 2 + 0, y_off * 2 + 1);
156
67.0k
            t->bx += txsw;
157
67.0k
            if (txw >= txh && t->bx < f->bw)
158
38.7k
                read_tx_tree(t, sub, depth + 1, masks,
159
38.7k
                             x_off * 2 + 1, y_off * 2 + 1);
160
67.0k
            t->bx -= txsw;
161
67.0k
        }
162
109k
        t->by -= txsh;
163
533k
    } else {
164
533k
        dav1d_memset_pow2[t_dim->lw](&t->a->tx[bx4], is_split ? TX_4X4 : txw);
165
533k
        dav1d_memset_pow2[t_dim->lh](&t->l.tx[by4], is_split ? TX_4X4 : txh);
166
533k
    }
167
642k
}
168
169
3.59M
static int neg_deinterleave(int diff, int ref, int max) {
170
3.59M
    if (!ref) return diff;
171
2.49M
    if (ref >= (max - 1)) return max - diff - 1;
172
2.16M
    if (2 * ref < max) {
173
1.29M
        if (diff <= 2 * ref) {
174
1.07M
            if (diff & 1)
175
151k
                return ref + ((diff + 1) >> 1);
176
923k
            else
177
923k
                return ref - (diff >> 1);
178
1.07M
        }
179
217k
        return diff;
180
1.29M
    } else {
181
871k
        if (diff <= 2 * (max - ref - 1)) {
182
737k
            if (diff & 1)
183
111k
                return ref + ((diff + 1) >> 1);
184
625k
            else
185
625k
                return ref - (diff >> 1);
186
737k
        }
187
133k
        return max - (diff + 1);
188
871k
    }
189
2.16M
}
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
259k
{
198
259k
    /*const*/ refmvs_block *const *r = &t->rt.r[(t->by & 31) + 5];
199
259k
    int count = 0;
200
259k
    int have_topleft = have_top && have_left;
201
259k
    int have_topright = imax(bw4, bh4) < 32 &&
202
253k
                        have_top && t->bx + bw4 < t->ts->tiling.col_end &&
203
181k
                        (intra_edge_flags & EDGE_I444_TOP_HAS_RIGHT);
204
205
576k
#define bs(rp) dav1d_block_dimensions[(rp)->bs]
206
727k
#define matches(rp) ((rp)->ref.ref[0] == ref + 1 && (rp)->ref.ref[1] == -1)
207
208
259k
    if (have_top) {
209
215k
        const refmvs_block *r2 = &r[-1][t->bx];
210
215k
        if (matches(r2)) {
211
144k
            masks[0] |= 1;
212
144k
            count = 1;
213
144k
        }
214
215k
        int aw4 = bs(r2)[0];
215
215k
        if (aw4 >= bw4) {
216
182k
            const int off = t->bx & (aw4 - 1);
217
182k
            if (off) have_topleft = 0;
218
182k
            if (aw4 - off > bw4) have_topright = 0;
219
182k
        } else {
220
32.5k
            unsigned mask = 1 << aw4;
221
75.4k
            for (int x = aw4; x < w4; x += aw4) {
222
42.9k
                r2 += aw4;
223
42.9k
                if (matches(r2)) {
224
23.5k
                    masks[0] |= mask;
225
23.5k
                    if (++count >= 8) return;
226
23.5k
                }
227
42.8k
                aw4 = bs(r2)[0];
228
42.8k
                mask <<= aw4;
229
42.8k
            }
230
32.5k
        }
231
215k
    }
232
258k
    if (have_left) {
233
226k
        /*const*/ refmvs_block *const *r2 = r;
234
226k
        if (matches(&r2[0][t->bx - 1])) {
235
153k
            masks[1] |= 1;
236
153k
            if (++count >= 8) return;
237
153k
        }
238
226k
        int lh4 = bs(&r2[0][t->bx - 1])[1];
239
226k
        if (lh4 >= bh4) {
240
189k
            if (t->by & (lh4 - 1)) have_topleft = 0;
241
189k
        } else {
242
37.4k
            unsigned mask = 1 << lh4;
243
87.4k
            for (int y = lh4; y < h4; y += lh4) {
244
50.2k
                r2 += lh4;
245
50.2k
                if (matches(&r2[0][t->bx - 1])) {
246
27.8k
                    masks[1] |= mask;
247
27.8k
                    if (++count >= 8) return;
248
27.8k
                }
249
50.0k
                lh4 = bs(&r2[0][t->bx - 1])[1];
250
50.0k
                mask <<= lh4;
251
50.0k
            }
252
37.4k
        }
253
226k
    }
254
258k
    if (have_topleft && matches(&r[-1][t->bx - 1])) {
255
69.4k
        masks[1] |= 1ULL << 32;
256
69.4k
        if (++count >= 8) return;
257
69.4k
    }
258
258k
    if (have_topright && matches(&r[-1][t->bx + bw4])) {
259
40.3k
        masks[0] |= 1ULL << 32;
260
40.3k
    }
261
258k
#undef matches
262
258k
}
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
7.91k
{
269
7.91k
    int pts[8][2 /* in, out */][2 /* x, y */], np = 0;
270
7.91k
    /*const*/ refmvs_block *const *r = &t->rt.r[(t->by & 31) + 5];
271
272
18.0k
#define add_sample(dx, dy, sx, sy, rp) do { \
273
18.0k
    pts[np][0][0] = 16 * (2 * dx + sx * bs(rp)[0]) - 8; \
274
18.0k
    pts[np][0][1] = 16 * (2 * dy + sy * bs(rp)[1]) - 8; \
275
18.0k
    pts[np][1][0] = pts[np][0][0] + (rp)->mv.mv[0].x; \
276
18.0k
    pts[np][1][1] = pts[np][0][1] + (rp)->mv.mv[0].y; \
277
18.0k
    np++; \
278
18.0k
} while (0)
279
280
    // use masks[] to find the projectable motion vectors in the edges
281
7.91k
    if ((unsigned) masks[0] == 1 && !(masks[1] >> 32)) {
282
2.20k
        const int off = t->bx & (bs(&r[-1][t->bx])[0] - 1);
283
2.20k
        add_sample(-off, 0, 1, -1, &r[-1][t->bx]);
284
9.61k
    } else for (unsigned off = 0, xmask = (uint32_t) masks[0]; np < 8 && xmask;) { // top
285
3.89k
        const int tz = ctz(xmask);
286
3.89k
        off += tz;
287
3.89k
        xmask >>= tz;
288
3.89k
        add_sample(off, 0, 1, -1, &r[-1][t->bx + off]);
289
3.89k
        xmask &= ~1;
290
3.89k
    }
291
7.91k
    if (np < 8 && masks[1] == 1) {
292
3.12k
        const int off = t->by & (bs(&r[0][t->bx - 1])[1] - 1);
293
3.12k
        add_sample(0, -off, -1, 1, &r[-off][t->bx - 1]);
294
8.62k
    } else for (unsigned off = 0, ymask = (uint32_t) masks[1]; np < 8 && ymask;) { // left
295
3.83k
        const int tz = ctz(ymask);
296
3.83k
        off += tz;
297
3.83k
        ymask >>= tz;
298
3.83k
        add_sample(0, off, -1, 1, &r[off][t->bx - 1]);
299
3.83k
        ymask &= ~1;
300
3.83k
    }
301
7.91k
    if (np < 8 && masks[1] >> 32) // top/left
302
2.82k
        add_sample(0, 0, -1, -1, &r[-1][t->bx - 1]);
303
7.91k
    if (np < 8 && masks[0] >> 32) // top/right
304
2.19k
        add_sample(bw4, 0, 1, -1, &r[-1][t->bx + bw4]);
305
7.91k
    assert(np > 0 && np <= 8);
306
7.91k
#undef bs
307
308
    // select according to motion vector difference against a threshold
309
7.91k
    int mvd[8], ret = 0;
310
7.91k
    const int thresh = 4 * iclip(imax(bw4, bh4), 4, 28);
311
26.0k
    for (int i = 0; i < np; i++) {
312
18.0k
        mvd[i] = abs(pts[i][1][0] - pts[i][0][0] - mv.x) +
313
18.0k
                 abs(pts[i][1][1] - pts[i][0][1] - mv.y);
314
18.0k
        if (mvd[i] > thresh)
315
6.03k
            mvd[i] = -1;
316
12.0k
        else
317
12.0k
            ret++;
318
18.0k
    }
319
7.91k
    if (!ret) {
320
1.78k
        ret = 1;
321
7.37k
    } else for (int i = 0, j = np - 1, k = 0; k < np - ret; k++, i++, j--) {
322
4.10k
        while (mvd[i] != -1) i++;
323
4.19k
        while (mvd[j] == -1) j--;
324
2.41k
        assert(i != j);
325
2.41k
        if (i > j) break;
326
        // replace the discarded samples;
327
1.24k
        mvd[i] = mvd[j];
328
1.24k
        memcpy(pts[i], pts[j], sizeof(*pts));
329
1.24k
    }
330
331
7.91k
    if (!dav1d_find_affine_int(pts, ret, bw4, bh4, mv, wmp, t->bx, t->by) &&
332
7.43k
        !dav1d_get_shear_params(wmp))
333
6.69k
    {
334
6.69k
        wmp->type = DAV1D_WM_TYPE_AFFINE;
335
6.69k
    } else
336
1.22k
        wmp->type = DAV1D_WM_TYPE_IDENTITY;
337
7.91k
}
338
339
271k
static inline int findoddzero(const uint8_t *buf, int len) {
340
298k
    for (int n = 0; n < len; n++)
341
285k
        if (!buf[n * 2]) return 1;
342
12.2k
    return 0;
343
271k
}
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
11.4M
{
353
11.4M
    if (color_idx < prio_count)
354
9.52M
        return p[color_idx];
355
1.89M
    unsigned rank = color_idx - prio_count + (mask & 1);
356
1.89M
    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
1.89M
    static const uint8_t free_offsets2[] = {
361
1.89M
        0x00, 0x00, 0x50, 0x15, 0x40, 0x15, 0xa0, 0x0a, 0x00, 0x15, 0x90, 0x0a,
362
1.89M
        0x80, 0x0a, 0xf0, 0x03, 0x00, 0x14, 0x50, 0x0a, 0x40, 0x0a, 0xe0, 0x03,
363
1.89M
        0x00, 0x0a, 0xd0, 0x03, 0xc0, 0x03, 0x00, 0x00, 0x00, 0x10, 0x50, 0x09,
364
1.89M
        0x40, 0x09, 0xa0, 0x03, 0x00, 0x09, 0x90, 0x03, 0x80, 0x03, 0x00, 0x00,
365
1.89M
        0x00, 0x08, 0x50, 0x03, 0x40, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
366
1.89M
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x05, 0x40, 0x05, 0xa0, 0x02,
367
1.89M
        0x00, 0x05, 0x90, 0x02, 0x80, 0x02, 0x00, 0x00, 0x00, 0x04, 0x50, 0x02,
368
1.89M
        0x40, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
369
1.89M
        0x00, 0x00, 0x50, 0x01, 0x40, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
370
1.89M
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
371
1.89M
    };
372
1.89M
    const unsigned byte_idx = 2 * (mask >> 2) + (rank >> 2);
373
1.89M
    assert(byte_idx < sizeof(free_offsets2));
374
1.89M
    return rank + ((free_offsets2[byte_idx] >> (2 * (rank & 3))) & 3);
375
1.89M
}
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
84.6k
{
383
84.6k
    Dav1dTileState *const ts = t->ts;
384
84.6k
    const ptrdiff_t stride = bw4 * 4;
385
84.6k
    assert(pal_idx);
386
84.6k
    uint8_t *const pal_tmp = t->scratch.pal_idx_uv;
387
84.6k
    pal_tmp[0] = dav1d_msac_decode_uniform(&ts->msac, pal_sz);
388
84.6k
    uint16_t (*const color_map_cdf)[8] =
389
84.6k
        ts->cdf.m.color_map[pl][pal_sz - 2];
390
391
84.6k
    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
532k
        for (int i = 1; i < 4 * (w4 + h4) - 1; i++) {
397
512k
            const int first = imin(i, w4 * 4 - 1);
398
512k
            const int last = imax(0, i - h4 * 4 + 1);
399
512k
            int have_top = i > first;
400
512k
            const uint8_t *pal_row = pal_tmp + first + (i - first) * stride;
401
5.00M
            for (int j = first; j >= last; have_top = 1, j--, pal_row += stride - 1) {
402
4.48M
                const int have_left = j > 0;
403
4.48M
                int ctx, p0;
404
4.48M
                if (!have_left) {
405
239k
                    ctx = 0;
406
239k
                    p0 = pal_row[-stride];
407
4.24M
                } else if (!have_top) {
408
272k
                    ctx = 0;
409
272k
                    p0 = pal_row[-1];
410
3.97M
                } else {
411
3.97M
                    const int l = pal_row[-1], tp = pal_row[-stride];
412
3.97M
                    const int tl = pal_row[-(stride + 1)];
413
3.97M
                    const int same_t_l = tp == l;
414
3.97M
                    const int same_t_tl = tp == tl;
415
3.97M
                    ctx = 2 + same_t_l + (same_t_l & same_t_tl);
416
3.97M
                    p0 = same_t_l ? tp : tl;
417
3.97M
                }
418
4.48M
                const int bit = dav1d_msac_decode_bool_adapt(
419
4.48M
                    &ts->msac, color_map_cdf[ctx]);
420
4.48M
                pal_tmp[(i - j) * stride + j] = bit ^ p0;
421
4.48M
            }
422
512k
        }
423
20.1k
        t->c->pal_dsp.pal_idx_finish(pal_idx, pal_tmp, bw4 * 4, bh4 * 4,
424
20.1k
                                     w4 * 4, h4 * 4);
425
20.1k
        return;
426
20.1k
    }
427
428
64.5k
    unsigned (*const symbol_adapt)(MsacContext *, uint16_t *, size_t) =
429
64.5k
        pal_sz <= 4 ? dav1d_msac_decode_symbol_adapt4 : dav1d_msac_decode_symbol_adapt8;
430
431
1.58M
    for (int i = 1; i < 4 * (w4 + h4) - 1; i++) {
432
        // top/left-to-bottom/right diagonals ("wave-front")
433
1.51M
        const int first = imin(i, w4 * 4 - 1);
434
1.51M
        const int last = imax(0, i - h4 * 4 + 1);
435
1.51M
        int have_top = i > first;
436
1.51M
        const uint8_t *pal_row = pal_tmp + first + (i - first) * stride;
437
12.9M
        for (int j = first; j >= last; have_top = 1, j--, pal_row += stride - 1) {
438
11.4M
            const int have_left = j > 0;
439
11.4M
            uint8_t p[3];
440
11.4M
            unsigned mask;
441
11.4M
            int ctx, prio_count;
442
11.4M
            if (!have_left) {
443
694k
                ctx = 0; prio_count = 1;
444
694k
                p[0] = pal_row[-stride];
445
694k
                mask = 1u << p[0];
446
10.7M
            } else if (!have_top) {
447
822k
                ctx = 0; prio_count = 1;
448
822k
                p[0] = pal_row[-1];
449
822k
                mask = 1u << p[0];
450
9.90M
            } else {
451
9.90M
                const int l = pal_row[-1], tp = pal_row[-stride];
452
9.90M
                const int tl = pal_row[-(stride + 1)];
453
9.90M
                const int same_t_l = tp == l;
454
9.90M
                const int same_t_tl = tp == tl;
455
9.90M
                const int same_l_tl = l == tl;
456
9.90M
                if (same_t_l & same_t_tl) {
457
4.58M
                    ctx = 4; prio_count = 1;
458
4.58M
                    p[0] = tp; mask = 1u << tp;
459
5.32M
                } else if (same_t_l) {
460
354k
                    ctx = 3; prio_count = 2;
461
354k
                    p[0] = tp; p[1] = tl;
462
354k
                    mask = (1u << tp) | (1u << tl);
463
4.96M
                } else if (same_t_tl | same_l_tl) {
464
3.86M
                    ctx = 2; prio_count = 2;
465
3.86M
                    p[0] = tl; p[1] = same_t_tl ? l : tp;
466
3.86M
                    mask = (1u << tl) | (1u << p[1]);
467
3.86M
                } else {
468
1.10M
                    ctx = 1; prio_count = 3;
469
1.10M
                    p[0] = imin(tp, l); p[1] = imax(tp, l); p[2] = tl;
470
1.10M
                    mask = (1u << tp) | (1u << l) | (1u << tl);
471
1.10M
                }
472
9.90M
            }
473
11.4M
            const int color_idx = symbol_adapt(&ts->msac, color_map_cdf[ctx], pal_sz - 1);
474
11.4M
            pal_tmp[(i - j) * stride + j] =
475
11.4M
                resolve_pal_color(color_idx, p, prio_count, mask);
476
11.4M
        }
477
1.51M
    }
478
479
64.5k
    t->c->pal_dsp.pal_idx_finish(pal_idx, pal_tmp, bw4 * 4, bh4 * 4,
480
64.5k
                                 w4 * 4, h4 * 4);
481
64.5k
}
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
1.95M
{
487
1.95M
    const Dav1dFrameContext *const f = t->f;
488
1.95M
    const uint8_t *const b_dim = dav1d_block_dimensions[bs];
489
1.95M
    const int bw4 = b_dim[0], bh4 = b_dim[1];
490
491
    // var-tx tree coding
492
1.95M
    uint16_t tx_split[2] = { 0 };
493
1.95M
    b->max_ytx = dav1d_max_txfm_size_for_bs[bs][0];
494
1.95M
    if (!b->skip && (f->frame_hdr->segmentation.lossless[b->seg_id] ||
495
951k
                     b->max_ytx == TX_4X4))
496
82.3k
    {
497
82.3k
        b->max_ytx = b->uvtx = TX_4X4;
498
82.3k
        if (f->frame_hdr->txfm_mode == DAV1D_TX_SWITCHABLE) {
499
27.7k
            dav1d_memset_pow2[b_dim[2]](&t->a->tx[bx4], TX_4X4);
500
27.7k
            dav1d_memset_pow2[b_dim[3]](&t->l.tx[by4], TX_4X4);
501
27.7k
        }
502
1.87M
    } else if (f->frame_hdr->txfm_mode != DAV1D_TX_SWITCHABLE || b->skip) {
503
1.53M
        if (f->frame_hdr->txfm_mode == DAV1D_TX_SWITCHABLE) {
504
304k
            dav1d_memset_pow2[b_dim[2]](&t->a->tx[bx4], b_dim[2 + 0]);
505
304k
            dav1d_memset_pow2[b_dim[3]](&t->l.tx[by4], b_dim[2 + 1]);
506
304k
        }
507
1.53M
        b->uvtx = dav1d_max_txfm_size_for_bs[bs][f->cur.p.layout];
508
1.53M
    } else {
509
338k
        assert(bw4 <= 16 || bh4 <= 16 || b->max_ytx == TX_64X64);
510
338k
        int y, x, y_off, x_off;
511
338k
        const TxfmInfo *const ytx = &dav1d_txfm_dimensions[b->max_ytx];
512
679k
        for (y = 0, y_off = 0; y < bh4; y += ytx->h, y_off++) {
513
687k
            for (x = 0, x_off = 0; x < bw4; x += ytx->w, x_off++) {
514
346k
                read_tx_tree(t, b->max_ytx, 0, tx_split, x_off, y_off);
515
                // contexts are updated inside read_tx_tree()
516
346k
                t->bx += ytx->w;
517
346k
            }
518
341k
            t->bx -= x;
519
341k
            t->by += ytx->h;
520
341k
        }
521
338k
        t->by -= y;
522
338k
        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
338k
        b->uvtx = dav1d_max_txfm_size_for_bs[bs][f->cur.p.layout];
526
338k
    }
527
1.95M
    assert(!(tx_split[0] & ~0x33));
528
1.95M
    b->tx_split0 = (uint8_t)tx_split[0];
529
1.95M
    b->tx_split1 = tx_split[1];
530
1.95M
}
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
47.3k
{
538
47.3k
    assert(f->frame_hdr->primary_ref_frame != DAV1D_PRIMARY_REF_NONE);
539
540
47.3k
    unsigned seg_id = 8;
541
47.3k
    ref_seg_map += by * stride + bx;
542
147k
    do {
543
1.88M
        for (int x = 0; x < w4; x++)
544
1.73M
            seg_id = imin(seg_id, ref_seg_map[x]);
545
147k
        ref_seg_map += stride;
546
147k
    } while (--h4 > 0 && seg_id);
547
47.3k
    assert(seg_id < 8);
548
549
47.3k
    return seg_id;
550
47.3k
}
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
785k
{
558
785k
    const enum InterPredMode mode = b->inter_mode;
559
785k
    const refmvs_block ALIGN(tmpl, 16) = (refmvs_block) {
560
785k
        .ref.ref = { b->ref[0] + 1, b->interintra_type ? 0 : -1 },
561
785k
        .mv.mv[0] = b->mv[0],
562
785k
        .bs = bs,
563
785k
        .mf = (mode == GLOBALMV && imin(bw4, bh4) >= 2) | ((mode == NEWMV) * 2),
564
785k
    };
565
785k
    c->refmvs_dsp.splat_mv(&t->rt.r[(t->by & 31) + 5], &tmpl, t->bx, bw4, bh4);
566
785k
}
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
977k
{
574
977k
    const refmvs_block ALIGN(tmpl, 16) = (refmvs_block) {
575
977k
        .ref.ref = { 0, -1 },
576
977k
        .mv.mv[0] = b->mv[0],
577
977k
        .bs = bs,
578
977k
        .mf = 0,
579
977k
    };
580
977k
    c->refmvs_dsp.splat_mv(&t->rt.r[(t->by & 31) + 5], &tmpl, t->bx, bw4, bh4);
581
977k
}
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
191k
{
589
191k
    assert(bw4 >= 2 && bh4 >= 2);
590
191k
    const enum CompInterPredMode mode = b->inter_mode;
591
191k
    const refmvs_block ALIGN(tmpl, 16) = (refmvs_block) {
592
191k
        .ref.ref = { b->ref[0] + 1, b->ref[1] + 1 },
593
191k
        .mv.mv = { b->mv[0], b->mv[1] },
594
191k
        .bs = bs,
595
191k
        .mf = (mode == GLOBALMV_GLOBALMV) | !!((1 << mode) & (0xbc)) * 2,
596
191k
    };
597
191k
    c->refmvs_dsp.splat_mv(&t->rt.r[(t->by & 31) + 5], &tmpl, t->bx, bw4, bh4);
598
191k
}
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
1.81M
{
605
1.81M
    const refmvs_block ALIGN(tmpl, 16) = (refmvs_block) {
606
1.81M
        .ref.ref = { 0, -1 },
607
1.81M
        .mv.mv[0].n = INVALID_MV,
608
1.81M
        .bs = bs,
609
1.81M
        .mf = 0,
610
1.81M
    };
611
1.81M
    c->refmvs_dsp.splat_mv(&t->rt.r[(t->by & 31) + 5], &tmpl, t->bx, bw4, bh4);
612
1.81M
}
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
2.20M
{
618
2.20M
    const int v_mul = 4 >> ss_ver;
619
2.20M
    if (!smp->scale) {
620
575k
        const int my = mvy >> (3 + ss_ver), dy = mvy & (15 >> !ss_ver);
621
575k
        *dst = imax(*dst, (by4 + bh4) * v_mul + my + 4 * !!dy);
622
1.62M
    } else {
623
1.62M
        int y = (by4 * v_mul << 4) + mvy * (1 << !ss_ver);
624
1.62M
        const int64_t tmp = (int64_t)(y) * smp->scale + (smp->scale - 0x4000) * 8;
625
1.62M
        y = apply_sign64((int)((llabs(tmp) + 128) >> 8), tmp) + 32;
626
1.62M
        const int bottom = ((y + (bh4 * v_mul - 1) * smp->step) >> 10) + 1 + 4;
627
1.62M
        *dst = imax(*dst, bottom);
628
1.62M
    }
629
2.20M
}
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
38.3k
{
636
38.3k
    const int h_mul = 4 >> ss_hor, v_mul = 4 >> ss_ver;
637
38.3k
    assert(!((b_dim[0] * h_mul) & 7) && !((b_dim[1] * v_mul) & 7));
638
38.3k
    const int32_t *const mat = wmp->matrix;
639
38.3k
    const int y = b_dim[1] * v_mul - 8; // lowest y
640
641
38.3k
    const int src_y = t->by * 4 + ((y + 4) << ss_ver);
642
38.3k
    const int64_t mat5_y = (int64_t) mat[5] * src_y + mat[1];
643
    // check left- and right-most blocks
644
99.8k
    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
61.5k
        const int src_x = t->bx * 4 + ((x + 4) << ss_hor);
648
61.5k
        const int64_t mvy = ((int64_t) mat[4] * src_x + mat5_y) >> ss_ver;
649
61.5k
        const int dy = (int) (mvy >> 16) - 4;
650
61.5k
        *dst = imax(*dst, dy + 4 + 8);
651
61.5k
    }
652
38.3k
}
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
31.9k
{
658
31.9k
    affine_lowest_px(t, dst, b_dim, wmp, 0, 0);
659
31.9k
}
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
8.62k
{
665
8.62k
    const Dav1dFrameContext *const f = t->f;
666
8.62k
    assert(f->cur.p.layout != DAV1D_PIXEL_LAYOUT_I400);
667
8.62k
    if (f->cur.p.layout == DAV1D_PIXEL_LAYOUT_I444)
668
2.25k
        affine_lowest_px_luma(t, dst, b_dim, wmp);
669
6.37k
    else
670
6.37k
        affine_lowest_px(t, dst, b_dim, wmp, f->cur.p.layout & DAV1D_PIXEL_LAYOUT_I420, 1);
671
8.62k
}
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
237k
{
678
237k
    assert(!(t->bx & 1) && !(t->by & 1));
679
237k
    const Dav1dFrameContext *const f = t->f;
680
237k
    /*const*/ refmvs_block **r = &t->rt.r[(t->by & 31) + 5];
681
237k
    const int ss_ver = is_chroma && f->cur.p.layout == DAV1D_PIXEL_LAYOUT_I420;
682
237k
    const int ss_hor = is_chroma && f->cur.p.layout != DAV1D_PIXEL_LAYOUT_I444;
683
237k
    const int h_mul = 4 >> ss_hor, v_mul = 4 >> ss_ver;
684
685
237k
    if (t->by > t->ts->tiling.row_start &&
686
206k
        (!is_chroma || b_dim[0] * h_mul + b_dim[1] * v_mul >= 16))
687
158k
    {
688
336k
        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
177k
            const refmvs_block *const a_r = &r[-1][t->bx + x + 1];
691
177k
            const uint8_t *const a_b_dim = dav1d_block_dimensions[a_r->bs];
692
693
177k
            if (a_r->ref.ref[0] > 0) {
694
171k
                const int oh4 = imin(b_dim[1], 16) >> 1;
695
171k
                mc_lowest_px(&dst[a_r->ref.ref[0] - 1][is_chroma], t->by,
696
171k
                             (oh4 * 3 + 3) >> 2, a_r->mv.mv[0].y, ss_ver,
697
171k
                             &f->svc[a_r->ref.ref[0] - 1][1]);
698
171k
                i++;
699
171k
            }
700
177k
            x += imax(a_b_dim[0], 2);
701
177k
        }
702
158k
    }
703
704
237k
    if (t->bx > t->ts->tiling.col_start)
705
443k
        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
231k
            const refmvs_block *const l_r = &r[y + 1][t->bx - 1];
708
231k
            const uint8_t *const l_b_dim = dav1d_block_dimensions[l_r->bs];
709
710
231k
            if (l_r->ref.ref[0] > 0) {
711
225k
                const int oh4 = iclip(l_b_dim[1], 2, b_dim[1]);
712
225k
                mc_lowest_px(&dst[l_r->ref.ref[0] - 1][is_chroma],
713
225k
                             t->by + y, oh4, l_r->mv.mv[0].y, ss_ver,
714
225k
                             &f->svc[l_r->ref.ref[0] - 1][1]);
715
225k
                i++;
716
225k
            }
717
231k
            y += imax(l_b_dim[1], 2);
718
231k
        }
719
237k
}
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
11.5M
                    const enum EdgeFlags intra_edge_flags) {
726
11.5M
    Dav1dTileState *const ts = t->ts;
727
11.5M
    const Dav1dFrameContext *const f = t->f;
728
11.5M
    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
11.5M
    const uint8_t *const b_dim = dav1d_block_dimensions[bs];
731
11.5M
    const int bx4 = t->bx & 31, by4 = t->by & 31;
732
11.5M
    const int ss_ver = f->cur.p.layout == DAV1D_PIXEL_LAYOUT_I420;
733
11.5M
    const int ss_hor = f->cur.p.layout != DAV1D_PIXEL_LAYOUT_I444;
734
11.5M
    const int cbx4 = bx4 >> ss_hor, cby4 = by4 >> ss_ver;
735
11.5M
    const int bw4 = b_dim[0], bh4 = b_dim[1];
736
11.5M
    const int w4 = imin(bw4, f->bw - t->bx), h4 = imin(bh4, f->bh - t->by);
737
11.5M
    const int cbw4 = (bw4 + ss_hor) >> ss_hor, cbh4 = (bh4 + ss_ver) >> ss_ver;
738
11.5M
    const int have_left = t->bx > ts->tiling.col_start;
739
11.5M
    const int have_top = t->by > ts->tiling.row_start;
740
11.5M
    const int has_chroma = f->cur.p.layout != DAV1D_PIXEL_LAYOUT_I400 &&
741
8.90M
                           (bw4 > ss_hor || t->bx & 1) &&
742
8.19M
                           (bh4 > ss_ver || t->by & 1);
743
744
11.5M
    if (t->frame_thread.pass == 2) {
745
4.16M
        if (b->intra) {
746
3.43M
            f->bd_fn.recon_b_intra(t, bs, intra_edge_flags, b);
747
748
3.43M
            const enum IntraPredMode y_mode_nofilt =
749
3.43M
                b->y_mode == FILTER_PRED ? DC_PRED : b->y_mode;
750
3.43M
#define set_ctx(rep_macro) \
751
6.87M
            rep_macro(edge->mode, off, y_mode_nofilt); \
752
6.87M
            rep_macro(edge->intra, off, 1)
753
3.43M
            BlockContext *edge = t->a;
754
10.3M
            for (int i = 0, off = bx4; i < 2; i++, off = by4, edge = &t->l) {
755
6.87M
                case_set(b_dim[2 + i]);
756
6.87M
            }
757
3.43M
#undef set_ctx
758
3.43M
            if (IS_INTER_OR_SWITCH(f->frame_hdr)) {
759
32.0k
                refmvs_block *const r = &t->rt.r[(t->by & 31) + 5 + bh4 - 1][t->bx];
760
187k
                for (int x = 0; x < bw4; x++) {
761
155k
                    r[x].ref.ref[0] = 0;
762
155k
                    r[x].bs = bs;
763
155k
                }
764
32.0k
                refmvs_block *const *rr = &t->rt.r[(t->by & 31) + 5];
765
32.0k
                const int bx = t->bx + bw4 - 1;
766
147k
                for (int y = 0; y < bh4 - 1; y++) {
767
115k
                    refmvs_block *d = &rr[y][bx];
768
115k
                    d->ref.ref[0] = 0;
769
115k
                    d->bs = bs;
770
115k
                }
771
32.0k
            }
772
773
3.43M
            if (has_chroma) {
774
2.29M
                uint8_t uv_mode = b->uv_mode;
775
2.29M
                dav1d_memset_pow2[ulog2(cbw4)](&t->a->uvmode[cbx4], uv_mode);
776
2.29M
                dav1d_memset_pow2[ulog2(cbh4)](&t->l.uvmode[cby4], uv_mode);
777
2.29M
            }
778
3.43M
        } else {
779
733k
            if (IS_INTER_OR_SWITCH(f->frame_hdr) /* not intrabc */ &&
780
428k
                b->comp_type == COMP_INTER_NONE && b->motion_mode == MM_WARP)
781
2.54k
            {
782
2.54k
                if (b->matrix[0] == INT16_MIN) {
783
370
                    t->warpmv.type = DAV1D_WM_TYPE_IDENTITY;
784
2.17k
                } else {
785
2.17k
                    t->warpmv.type = DAV1D_WM_TYPE_AFFINE;
786
2.17k
                    t->warpmv.matrix[2] = b->matrix[0] + 0x10000;
787
2.17k
                    t->warpmv.matrix[3] = b->matrix[1];
788
2.17k
                    t->warpmv.matrix[4] = b->matrix[2];
789
2.17k
                    t->warpmv.matrix[5] = b->matrix[3] + 0x10000;
790
2.17k
                    dav1d_set_affine_mv2d(bw4, bh4, b->mv2d, &t->warpmv,
791
2.17k
                                          t->bx, t->by);
792
2.17k
                    dav1d_get_shear_params(&t->warpmv);
793
2.17k
#define signabs(v) v < 0 ? '-' : ' ', abs(v)
794
2.17k
                    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
2.17k
#undef signabs
809
2.17k
                }
810
2.54k
            }
811
733k
            if (f->bd_fn.recon_b_inter(t, bs, b)) return -1;
812
813
733k
            const uint8_t *const filter = dav1d_filter_dir[b->filter2d];
814
733k
            BlockContext *edge = t->a;
815
2.19M
            for (int i = 0, off = bx4; i < 2; i++, off = by4, edge = &t->l) {
816
1.46M
#define set_ctx(rep_macro) \
817
1.46M
                rep_macro(edge->filter[0], off, filter[0]); \
818
1.46M
                rep_macro(edge->filter[1], off, filter[1]); \
819
1.46M
                rep_macro(edge->intra, off, 0)
820
1.46M
                case_set(b_dim[2 + i]);
821
1.46M
#undef set_ctx
822
1.46M
            }
823
824
733k
            if (IS_INTER_OR_SWITCH(f->frame_hdr)) {
825
428k
                refmvs_block *const r = &t->rt.r[(t->by & 31) + 5 + bh4 - 1][t->bx];
826
428k
                const int ref1 = b->ref[0] + 1;
827
428k
                const union mv mv1 = b->mv[0];
828
2.26M
                for (int x = 0; x < bw4; x++) {
829
1.84M
                    r[x].ref.ref[0] = ref1;
830
1.84M
                    r[x].mv.mv[0] = mv1;
831
1.84M
                    r[x].bs = bs;
832
1.84M
                }
833
428k
                refmvs_block *const *rr = &t->rt.r[(t->by & 31) + 5];
834
428k
                const int bx = t->bx + bw4 - 1;
835
1.87M
                for (int y = 0; y < bh4 - 1; y++) {
836
1.44M
                    refmvs_block* d = &rr[y][bx];
837
1.44M
                    d->ref.ref[0] = ref1;
838
1.44M
                    d->mv.mv[0] = mv1;
839
1.44M
                    d->bs = bs;
840
1.44M
                }
841
428k
            }
842
843
733k
            if (has_chroma) {
844
485k
                dav1d_memset_pow2[ulog2(cbw4)](&t->a->uvmode[cbx4], DC_PRED);
845
485k
                dav1d_memset_pow2[ulog2(cbh4)](&t->l.uvmode[cby4], DC_PRED);
846
485k
            }
847
733k
        }
848
4.16M
        return 0;
849
4.16M
    }
850
851
7.39M
    const int cw4 = (w4 + ss_hor) >> ss_hor, ch4 = (h4 + ss_ver) >> ss_ver;
852
853
7.39M
    b->bl = bl;
854
7.39M
    b->bp = bp;
855
7.39M
    b->bs = bs;
856
857
7.39M
    const Dav1dSegmentationData *seg = NULL;
858
859
    // segment_id (if seg_feature for skip/ref/gmv is enabled)
860
7.39M
    int seg_pred = 0;
861
7.39M
    if (f->frame_hdr->segmentation.enabled) {
862
3.84M
        if (!f->frame_hdr->segmentation.update_map) {
863
64.5k
            if (f->prev_segmap) {
864
43.3k
                unsigned seg_id = get_prev_frame_segid(f, t->by, t->bx, w4, h4,
865
43.3k
                                                       f->prev_segmap,
866
43.3k
                                                       f->b4_stride);
867
43.3k
                if (seg_id >= 8) return -1;
868
43.3k
                b->seg_id = seg_id;
869
43.3k
            } else {
870
21.1k
                b->seg_id = 0;
871
21.1k
            }
872
64.5k
            seg = &f->frame_hdr->segmentation.seg_data.d[b->seg_id];
873
3.78M
        } else if (f->frame_hdr->segmentation.seg_data.preskip) {
874
3.46M
            if (f->frame_hdr->segmentation.temporal &&
875
13.6k
                (seg_pred = dav1d_msac_decode_bool_adapt(&ts->msac,
876
13.6k
                                ts->cdf.m.seg_pred[t->a->seg_pred[bx4] +
877
13.6k
                                t->l.seg_pred[by4]])))
878
7.06k
            {
879
                // temporal predicted seg_id
880
7.06k
                if (f->prev_segmap) {
881
3.44k
                    unsigned seg_id = get_prev_frame_segid(f, t->by, t->bx,
882
3.44k
                                                           w4, h4,
883
3.44k
                                                           f->prev_segmap,
884
3.44k
                                                           f->b4_stride);
885
3.44k
                    if (seg_id >= 8) return -1;
886
3.44k
                    b->seg_id = seg_id;
887
3.62k
                } else {
888
3.62k
                    b->seg_id = 0;
889
3.62k
                }
890
3.46M
            } else {
891
3.46M
                int seg_ctx;
892
3.46M
                const unsigned pred_seg_id =
893
3.46M
                    get_cur_frame_segid(t->by, t->bx, have_top, have_left,
894
3.46M
                                        &seg_ctx, f->cur_segmap, f->b4_stride);
895
3.46M
                const unsigned diff = dav1d_msac_decode_symbol_adapt8(&ts->msac,
896
3.46M
                                          ts->cdf.m.seg_id[seg_ctx],
897
3.46M
                                          DAV1D_MAX_SEGMENTS - 1);
898
3.46M
                const unsigned last_active_seg_id =
899
3.46M
                    f->frame_hdr->segmentation.seg_data.last_active_segid;
900
3.46M
                b->seg_id = neg_deinterleave(diff, pred_seg_id,
901
3.46M
                                             last_active_seg_id + 1);
902
3.46M
                if (b->seg_id > last_active_seg_id) b->seg_id = 0; // error?
903
3.46M
                if (b->seg_id >= DAV1D_MAX_SEGMENTS) b->seg_id = 0; // error?
904
3.46M
            }
905
906
3.46M
            if (DEBUG_BLOCK_INFO)
907
0
                printf("Post-segid[preskip;%d]: r=%d\n",
908
0
                       b->seg_id, ts->msac.rng);
909
910
3.46M
            seg = &f->frame_hdr->segmentation.seg_data.d[b->seg_id];
911
3.46M
        }
912
3.84M
    } else {
913
3.54M
        b->seg_id = 0;
914
3.54M
    }
915
916
    // skip_mode
917
7.39M
    if ((!seg || (!seg->globalmv && seg->ref == -1 && !seg->skip)) &&
918
4.63M
        f->frame_hdr->skip_mode_enabled && imin(bw4, bh4) > 1)
919
11.5k
    {
920
11.5k
        const int smctx = t->a->skip_mode[bx4] + t->l.skip_mode[by4];
921
11.5k
        b->skip_mode = dav1d_msac_decode_bool_adapt(&ts->msac,
922
11.5k
                           ts->cdf.m.skip_mode[smctx]);
923
11.5k
        if (DEBUG_BLOCK_INFO)
924
0
            printf("Post-skipmode[%d]: r=%d\n", b->skip_mode, ts->msac.rng);
925
7.38M
    } else {
926
7.38M
        b->skip_mode = 0;
927
7.38M
    }
928
929
    // skip
930
7.40M
    if (b->skip_mode || (seg && seg->skip)) {
931
2.14M
        b->skip = 1;
932
5.25M
    } else {
933
5.25M
        const int sctx = t->a->skip[bx4] + t->l.skip[by4];
934
5.25M
        b->skip = dav1d_msac_decode_bool_adapt(&ts->msac, ts->cdf.m.skip[sctx]);
935
5.25M
        if (DEBUG_BLOCK_INFO)
936
0
            printf("Post-skip[%d]: r=%d\n", b->skip, ts->msac.rng);
937
5.25M
    }
938
939
    // segment_id
940
7.39M
    if (f->frame_hdr->segmentation.enabled &&
941
3.85M
        f->frame_hdr->segmentation.update_map &&
942
3.78M
        !f->frame_hdr->segmentation.seg_data.preskip)
943
316k
    {
944
316k
        if (!b->skip && f->frame_hdr->segmentation.temporal &&
945
17.7k
            (seg_pred = dav1d_msac_decode_bool_adapt(&ts->msac,
946
17.7k
                            ts->cdf.m.seg_pred[t->a->seg_pred[bx4] +
947
17.7k
                            t->l.seg_pred[by4]])))
948
8.68k
        {
949
            // temporal predicted seg_id
950
8.68k
            if (f->prev_segmap) {
951
538
                unsigned seg_id = get_prev_frame_segid(f, t->by, t->bx, w4, h4,
952
538
                                                       f->prev_segmap,
953
538
                                                       f->b4_stride);
954
538
                if (seg_id >= 8) return -1;
955
538
                b->seg_id = seg_id;
956
8.14k
            } else {
957
8.14k
                b->seg_id = 0;
958
8.14k
            }
959
308k
        } else {
960
308k
            int seg_ctx;
961
308k
            const unsigned pred_seg_id =
962
308k
                get_cur_frame_segid(t->by, t->bx, have_top, have_left,
963
308k
                                    &seg_ctx, f->cur_segmap, f->b4_stride);
964
308k
            if (b->skip) {
965
179k
                b->seg_id = pred_seg_id;
966
179k
            } else {
967
129k
                const unsigned diff = dav1d_msac_decode_symbol_adapt8(&ts->msac,
968
129k
                                          ts->cdf.m.seg_id[seg_ctx],
969
129k
                                          DAV1D_MAX_SEGMENTS - 1);
970
129k
                const unsigned last_active_seg_id =
971
129k
                    f->frame_hdr->segmentation.seg_data.last_active_segid;
972
129k
                b->seg_id = neg_deinterleave(diff, pred_seg_id,
973
129k
                                             last_active_seg_id + 1);
974
129k
                if (b->seg_id > last_active_seg_id) b->seg_id = 0; // error?
975
129k
            }
976
308k
            if (b->seg_id >= DAV1D_MAX_SEGMENTS) b->seg_id = 0; // error?
977
308k
        }
978
979
316k
        seg = &f->frame_hdr->segmentation.seg_data.d[b->seg_id];
980
981
316k
        if (DEBUG_BLOCK_INFO)
982
0
            printf("Post-segid[postskip;%d]: r=%d\n",
983
0
                   b->seg_id, ts->msac.rng);
984
316k
    }
985
986
    // cdef index
987
7.39M
    if (!b->skip) {
988
3.21M
        const int idx = f->seq_hdr->sb128 ? ((t->bx & 16) >> 4) +
989
2.02M
                                           ((t->by & 16) >> 3) : 0;
990
3.21M
        if (t->cur_sb_cdef_idx_ptr[idx] == -1) {
991
749k
            const int v = dav1d_msac_decode_bools(&ts->msac,
992
749k
                              f->frame_hdr->cdef.n_bits);
993
749k
            t->cur_sb_cdef_idx_ptr[idx] = v;
994
749k
            if (bw4 > 16) t->cur_sb_cdef_idx_ptr[idx + 1] = v;
995
749k
            if (bh4 > 16) t->cur_sb_cdef_idx_ptr[idx + 2] = v;
996
749k
            if (bw4 == 32 && bh4 == 32) t->cur_sb_cdef_idx_ptr[idx + 3] = v;
997
998
749k
            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
749k
        }
1002
3.21M
    }
1003
1004
    // delta-q/lf
1005
7.39M
    if (!((t->bx | t->by) & (31 >> !f->seq_hdr->sb128))) {
1006
1.10M
        const int prev_qidx = ts->last_qidx;
1007
1.10M
        const int have_delta_q = f->frame_hdr->delta.q.present &&
1008
369k
            (bs != (f->seq_hdr->sb128 ? BS_128x128 : BS_64x64) || !b->skip);
1009
1010
1.10M
        uint32_t prev_delta_lf = ts->last_delta_lf.u32;
1011
1012
1.10M
        if (have_delta_q) {
1013
327k
            int delta_q = dav1d_msac_decode_symbol_adapt4(&ts->msac,
1014
327k
                                                          ts->cdf.m.delta_q, 3);
1015
327k
            if (delta_q == 3) {
1016
25.4k
                const int n_bits = 1 + dav1d_msac_decode_bools(&ts->msac, 3);
1017
25.4k
                delta_q = dav1d_msac_decode_bools(&ts->msac, n_bits) +
1018
25.4k
                          1 + (1 << n_bits);
1019
25.4k
            }
1020
327k
            if (delta_q) {
1021
62.0k
                if (dav1d_msac_decode_bool_equi(&ts->msac)) delta_q = -delta_q;
1022
62.0k
                delta_q *= 1 << f->frame_hdr->delta.q.res_log2;
1023
62.0k
            }
1024
327k
            ts->last_qidx = iclip(ts->last_qidx + delta_q, 1, 255);
1025
327k
            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
327k
            if (f->frame_hdr->delta.lf.present) {
1030
159k
                const int n_lfs = f->frame_hdr->delta.lf.multi ?
1031
109k
                    f->cur.p.layout != DAV1D_PIXEL_LAYOUT_I400 ? 4 : 2 : 1;
1032
1033
602k
                for (int i = 0; i < n_lfs; i++) {
1034
443k
                    int delta_lf = dav1d_msac_decode_symbol_adapt4(&ts->msac,
1035
443k
                        ts->cdf.m.delta_lf[i + f->frame_hdr->delta.lf.multi], 3);
1036
443k
                    if (delta_lf == 3) {
1037
26.9k
                        const int n_bits = 1 + dav1d_msac_decode_bools(&ts->msac, 3);
1038
26.9k
                        delta_lf = dav1d_msac_decode_bools(&ts->msac, n_bits) +
1039
26.9k
                                   1 + (1 << n_bits);
1040
26.9k
                    }
1041
443k
                    if (delta_lf) {
1042
80.6k
                        if (dav1d_msac_decode_bool_equi(&ts->msac))
1043
50.4k
                            delta_lf = -delta_lf;
1044
80.6k
                        delta_lf *= 1 << f->frame_hdr->delta.lf.res_log2;
1045
80.6k
                    }
1046
443k
                    ts->last_delta_lf.i8[i] =
1047
443k
                        iclip(ts->last_delta_lf.i8[i] + delta_lf, -63, 63);
1048
443k
                    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
443k
                }
1052
159k
            }
1053
327k
        }
1054
1.10M
        if (ts->last_qidx == f->frame_hdr->quant.yac) {
1055
            // assign frame-wide q values to this sb
1056
865k
            ts->dq = f->dq;
1057
865k
        } else if (ts->last_qidx != prev_qidx) {
1058
            // find sb-specific quant parameters
1059
38.2k
            init_quant_tables(f->seq_hdr, f->frame_hdr, ts->last_qidx, ts->dqmem);
1060
38.2k
            ts->dq = ts->dqmem;
1061
38.2k
        }
1062
1.10M
        if (!ts->last_delta_lf.u32) {
1063
            // assign frame-wide lf values to this sb
1064
959k
            ts->lflvl = f->lf.lvl;
1065
959k
        } else if (ts->last_delta_lf.u32 != prev_delta_lf) {
1066
            // find sb-specific lf lvl parameters
1067
47.0k
            ts->lflvl = ts->lflvlmem;
1068
47.0k
            dav1d_calc_lf_values(ts->lflvlmem, f->frame_hdr, ts->last_delta_lf.i8);
1069
47.0k
        }
1070
1.10M
    }
1071
1072
7.39M
    if (b->skip_mode) {
1073
1.32k
        b->intra = 0;
1074
7.39M
    } else if (IS_INTER_OR_SWITCH(f->frame_hdr)) {
1075
1.07M
        if (seg && (seg->ref >= 0 || seg->globalmv)) {
1076
213k
            b->intra = !seg->ref;
1077
859k
        } else {
1078
859k
            const int ictx = get_intra_ctx(t->a, &t->l, by4, bx4,
1079
859k
                                           have_top, have_left);
1080
859k
            b->intra = !dav1d_msac_decode_bool_adapt(&ts->msac,
1081
859k
                            ts->cdf.m.intra[ictx]);
1082
859k
            if (DEBUG_BLOCK_INFO)
1083
0
                printf("Post-intra[%d]: r=%d\n", b->intra, ts->msac.rng);
1084
859k
        }
1085
6.32M
    } else if (f->frame_hdr->allow_intrabc) {
1086
2.69M
        b->intra = !dav1d_msac_decode_bool_adapt(&ts->msac, ts->cdf.m.intrabc);
1087
2.69M
        if (DEBUG_BLOCK_INFO)
1088
0
            printf("Post-intrabcflag[%d]: r=%d\n", b->intra, ts->msac.rng);
1089
3.63M
    } else {
1090
3.63M
        b->intra = 1;
1091
3.63M
    }
1092
1093
    // intra/inter-specific stuff
1094
7.39M
    if (b->intra) {
1095
5.45M
        uint16_t *const ymode_cdf = IS_INTER_OR_SWITCH(f->frame_hdr) ?
1096
97.2k
            ts->cdf.m.y_mode[dav1d_ymode_size_context[bs]] :
1097
5.45M
            ts->cdf.kfym[dav1d_intra_mode_context[t->a->mode[bx4]]]
1098
5.35M
                        [dav1d_intra_mode_context[t->l.mode[by4]]];
1099
5.45M
        b->y_mode = dav1d_msac_decode_symbol_adapt16(&ts->msac, ymode_cdf,
1100
5.45M
                                                     N_INTRA_PRED_MODES - 1);
1101
5.45M
        if (DEBUG_BLOCK_INFO)
1102
0
            printf("Post-ymode[%d]: r=%d\n", b->y_mode, ts->msac.rng);
1103
1104
        // angle delta
1105
5.45M
        if (b_dim[2] + b_dim[3] >= 2 && b->y_mode >= VERT_PRED &&
1106
2.32M
            b->y_mode <= VERT_LEFT_PRED)
1107
1.21M
        {
1108
1.21M
            uint16_t *const acdf = ts->cdf.m.angle_delta[b->y_mode - VERT_PRED];
1109
1.21M
            const int angle = dav1d_msac_decode_symbol_adapt8(&ts->msac, acdf, 6);
1110
1.21M
            b->y_angle = angle - 3;
1111
4.23M
        } else {
1112
4.23M
            b->y_angle = 0;
1113
4.23M
        }
1114
1115
5.45M
        if (has_chroma) {
1116
3.60M
            const int cfl_allowed = f->frame_hdr->segmentation.lossless[b->seg_id] ?
1117
3.54M
                cbw4 == 1 && cbh4 == 1 : !!(cfl_allowed_mask & (1 << bs));
1118
3.60M
            uint16_t *const uvmode_cdf = ts->cdf.m.uv_mode[cfl_allowed][b->y_mode];
1119
3.60M
            b->uv_mode = dav1d_msac_decode_symbol_adapt16(&ts->msac, uvmode_cdf,
1120
3.60M
                             N_UV_INTRA_PRED_MODES - 1 - !cfl_allowed);
1121
3.60M
            if (DEBUG_BLOCK_INFO)
1122
0
                printf("Post-uvmode[%d]: r=%d\n", b->uv_mode, ts->msac.rng);
1123
1124
3.60M
            b->uv_angle = 0;
1125
3.60M
            if (b->uv_mode == CFL_PRED) {
1126
810k
#define SIGN(a) (!!(a) + ((a) > 0))
1127
810k
                const int sign = dav1d_msac_decode_symbol_adapt8(&ts->msac,
1128
810k
                                     ts->cdf.m.cfl_sign, 7) + 1;
1129
810k
                const int sign_u = sign * 0x56 >> 8, sign_v = sign - sign_u * 3;
1130
810k
                assert(sign_u == sign / 3);
1131
810k
                if (sign_u) {
1132
765k
                    const int ctx = (sign_u == 2) * 3 + sign_v;
1133
765k
                    b->cfl_alpha[0] = dav1d_msac_decode_symbol_adapt16(&ts->msac,
1134
765k
                                          ts->cdf.m.cfl_alpha[ctx], 15) + 1;
1135
765k
                    if (sign_u == 1) b->cfl_alpha[0] = -b->cfl_alpha[0];
1136
765k
                } else {
1137
44.9k
                    b->cfl_alpha[0] = 0;
1138
44.9k
                }
1139
810k
                if (sign_v) {
1140
581k
                    const int ctx = (sign_v == 2) * 3 + sign_u;
1141
581k
                    b->cfl_alpha[1] = dav1d_msac_decode_symbol_adapt16(&ts->msac,
1142
581k
                                          ts->cdf.m.cfl_alpha[ctx], 15) + 1;
1143
581k
                    if (sign_v == 1) b->cfl_alpha[1] = -b->cfl_alpha[1];
1144
581k
                } else {
1145
228k
                    b->cfl_alpha[1] = 0;
1146
228k
                }
1147
810k
#undef SIGN
1148
810k
                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
2.79M
            } else if (b_dim[2] + b_dim[3] >= 2 && b->uv_mode >= VERT_PRED &&
1152
1.46M
                       b->uv_mode <= VERT_LEFT_PRED)
1153
758k
            {
1154
758k
                uint16_t *const acdf = ts->cdf.m.angle_delta[b->uv_mode - VERT_PRED];
1155
758k
                const int angle = dav1d_msac_decode_symbol_adapt8(&ts->msac, acdf, 6);
1156
758k
                b->uv_angle = angle - 3;
1157
758k
            }
1158
3.60M
        }
1159
1160
5.45M
        b->pal_sz[0] = b->pal_sz[1] = 0;
1161
5.45M
        if (f->frame_hdr->allow_screen_content_tools &&
1162
2.33M
            imax(bw4, bh4) <= 16 && bw4 + bh4 >= 4)
1163
1.76M
        {
1164
1.76M
            const int sz_ctx = b_dim[2] + b_dim[3] - 2;
1165
1.76M
            if (b->y_mode == DC_PRED) {
1166
808k
                const int pal_ctx = (t->a->pal_sz[bx4] > 0) + (t->l.pal_sz[by4] > 0);
1167
808k
                const int use_y_pal = dav1d_msac_decode_bool_adapt(&ts->msac,
1168
808k
                                          ts->cdf.m.pal_y[sz_ctx][pal_ctx]);
1169
808k
                if (DEBUG_BLOCK_INFO)
1170
0
                    printf("Post-y_pal[%d]: r=%d\n", use_y_pal, ts->msac.rng);
1171
808k
                if (use_y_pal)
1172
64.8k
                    f->bd_fn.read_pal_plane(t, b, 0, sz_ctx, bx4, by4);
1173
808k
            }
1174
1175
1.76M
            if (has_chroma && b->uv_mode == DC_PRED) {
1176
453k
                const int pal_ctx = b->pal_sz[0] > 0;
1177
453k
                const int use_uv_pal = dav1d_msac_decode_bool_adapt(&ts->msac,
1178
453k
                                           ts->cdf.m.pal_uv[pal_ctx]);
1179
453k
                if (DEBUG_BLOCK_INFO)
1180
0
                    printf("Post-uv_pal[%d]: r=%d\n", use_uv_pal, ts->msac.rng);
1181
453k
                if (use_uv_pal) // see aomedia bug 2183 for why we use luma coordinates
1182
19.7k
                    f->bd_fn.read_pal_uv(t, b, sz_ctx, bx4, by4);
1183
453k
            }
1184
1.76M
        }
1185
1186
5.45M
        if (b->y_mode == DC_PRED && !b->pal_sz[0] &&
1187
2.04M
            imax(b_dim[2], b_dim[3]) <= 3 && f->seq_hdr->filter_intra)
1188
895k
        {
1189
895k
            const int is_filter = dav1d_msac_decode_bool_adapt(&ts->msac,
1190
895k
                                      ts->cdf.m.use_filter_intra[bs]);
1191
895k
            if (is_filter) {
1192
598k
                b->y_mode = FILTER_PRED;
1193
598k
                b->y_angle = dav1d_msac_decode_symbol_adapt8(&ts->msac,
1194
598k
                                 ts->cdf.m.filter_intra, 4);
1195
598k
            }
1196
895k
            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
895k
        }
1200
1201
5.45M
        if (b->pal_sz[0]) {
1202
64.8k
            uint8_t *pal_idx;
1203
64.8k
            if (t->frame_thread.pass) {
1204
64.8k
                const int p = t->frame_thread.pass & 1;
1205
64.8k
                assert(ts->frame_thread[p].pal_idx);
1206
64.8k
                pal_idx = ts->frame_thread[p].pal_idx;
1207
64.8k
                ts->frame_thread[p].pal_idx += bw4 * bh4 * 8;
1208
64.8k
            } else
1209
0
                pal_idx = t->scratch.pal_idx_y;
1210
64.8k
            read_pal_indices(t, pal_idx, b->pal_sz[0], 0, w4, h4, bw4, bh4);
1211
64.8k
            if (DEBUG_BLOCK_INFO)
1212
0
                printf("Post-y-pal-indices: r=%d\n", ts->msac.rng);
1213
64.8k
        }
1214
1215
5.45M
        if (has_chroma && b->pal_sz[1]) {
1216
19.7k
            uint8_t *pal_idx;
1217
19.7k
            if (t->frame_thread.pass) {
1218
19.7k
                const int p = t->frame_thread.pass & 1;
1219
19.7k
                assert(ts->frame_thread[p].pal_idx);
1220
19.7k
                pal_idx = ts->frame_thread[p].pal_idx;
1221
19.7k
                ts->frame_thread[p].pal_idx += cbw4 * cbh4 * 8;
1222
19.7k
            } else
1223
0
                pal_idx = t->scratch.pal_idx_uv;
1224
19.7k
            read_pal_indices(t, pal_idx, b->pal_sz[1], 1, cw4, ch4, cbw4, cbh4);
1225
19.7k
            if (DEBUG_BLOCK_INFO)
1226
0
                printf("Post-uv-pal-indices: r=%d\n", ts->msac.rng);
1227
19.7k
        }
1228
1229
5.45M
        const TxfmInfo *t_dim;
1230
5.45M
        if (f->frame_hdr->segmentation.lossless[b->seg_id]) {
1231
112k
            b->tx = b->uvtx = (int) TX_4X4;
1232
112k
            t_dim = &dav1d_txfm_dimensions[TX_4X4];
1233
5.34M
        } else {
1234
5.34M
            b->tx = dav1d_max_txfm_size_for_bs[bs][0];
1235
5.34M
            b->uvtx = dav1d_max_txfm_size_for_bs[bs][f->cur.p.layout];
1236
5.34M
            t_dim = &dav1d_txfm_dimensions[b->tx];
1237
5.34M
            if (f->frame_hdr->txfm_mode == DAV1D_TX_SWITCHABLE && t_dim->max > TX_4X4) {
1238
1.31M
                const int tctx = get_tx_ctx(t->a, &t->l, t_dim, by4, bx4);
1239
1.31M
                uint16_t *const tx_cdf = ts->cdf.m.txsz[t_dim->max - 1][tctx];
1240
1.31M
                int depth = dav1d_msac_decode_symbol_adapt4(&ts->msac, tx_cdf,
1241
1.31M
                                imin(t_dim->max, 2));
1242
1243
2.30M
                while (depth--) {
1244
990k
                    b->tx = t_dim->sub;
1245
990k
                    t_dim = &dav1d_txfm_dimensions[b->tx];
1246
990k
                }
1247
1.31M
            }
1248
5.34M
            if (DEBUG_BLOCK_INFO)
1249
0
                printf("Post-tx[%d]: r=%d\n", b->tx, ts->msac.rng);
1250
5.34M
        }
1251
1252
        // reconstruction
1253
5.45M
        if (t->frame_thread.pass == 1) {
1254
5.45M
            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
5.45M
        if (f->frame_hdr->loopfilter.level_y[0] ||
1260
2.47M
            f->frame_hdr->loopfilter.level_y[1])
1261
3.32M
        {
1262
3.32M
            dav1d_create_lf_mask_intra(t->lf_mask, f->lf.level, f->b4_stride,
1263
3.32M
                                       (const uint8_t (*)[8][2])
1264
3.32M
                                       &ts->lflvl[b->seg_id][0][0][0],
1265
3.32M
                                       t->bx, t->by, f->w4, f->h4, bs,
1266
3.32M
                                       b->tx, b->uvtx, f->cur.p.layout,
1267
3.32M
                                       &t->a->tx_lpf_y[bx4], &t->l.tx_lpf_y[by4],
1268
3.32M
                                       has_chroma ? &t->a->tx_lpf_uv[cbx4] : NULL,
1269
3.32M
                                       has_chroma ? &t->l.tx_lpf_uv[cby4] : NULL);
1270
3.32M
        }
1271
        // update contexts
1272
5.45M
        const enum IntraPredMode y_mode_nofilt =
1273
5.45M
            b->y_mode == FILTER_PRED ? DC_PRED : b->y_mode;
1274
5.45M
        BlockContext *edge = t->a;
1275
16.3M
        for (int i = 0, off = bx4; i < 2; i++, off = by4, edge = &t->l) {
1276
10.9M
            int t_lsz = ((uint8_t *) &t_dim->lw)[i]; // lw then lh
1277
10.9M
#define set_ctx(rep_macro) \
1278
10.9M
            rep_macro(edge->tx_intra, off, t_lsz); \
1279
10.9M
            rep_macro(edge->tx, off, t_lsz); \
1280
10.9M
            rep_macro(edge->mode, off, y_mode_nofilt); \
1281
10.9M
            rep_macro(edge->pal_sz, off, b->pal_sz[0]); \
1282
10.9M
            rep_macro(edge->seg_pred, off, seg_pred); \
1283
10.9M
            rep_macro(edge->skip_mode, off, 0); \
1284
10.9M
            rep_macro(edge->intra, off, 1); \
1285
10.9M
            rep_macro(edge->skip, off, b->skip); \
1286
            /* see aomedia bug 2183 for why we use luma coordinates here */ \
1287
10.9M
            rep_macro(t->pal_sz_uv[i], off, (has_chroma ? b->pal_sz[1] : 0)); \
1288
10.9M
            if (IS_INTER_OR_SWITCH(f->frame_hdr)) { \
1289
194k
                rep_macro(edge->comp_type, off, COMP_INTER_NONE); \
1290
194k
                rep_macro(edge->ref[0], off, ((uint8_t) -1)); \
1291
194k
                rep_macro(edge->ref[1], off, ((uint8_t) -1)); \
1292
194k
                rep_macro(edge->filter[0], off, DAV1D_N_SWITCHABLE_FILTERS); \
1293
194k
                rep_macro(edge->filter[1], off, DAV1D_N_SWITCHABLE_FILTERS); \
1294
194k
            }
1295
10.9M
            case_set(b_dim[2 + i]);
1296
10.9M
#undef set_ctx
1297
10.9M
        }
1298
5.45M
        if (b->pal_sz[0])
1299
64.8k
            f->bd_fn.copy_pal_block_y(t, bx4, by4, bw4, bh4);
1300
5.45M
        if (has_chroma) {
1301
3.60M
            uint8_t uv_mode = b->uv_mode;
1302
3.60M
            dav1d_memset_pow2[ulog2(cbw4)](&t->a->uvmode[cbx4], uv_mode);
1303
3.60M
            dav1d_memset_pow2[ulog2(cbh4)](&t->l.uvmode[cby4], uv_mode);
1304
3.60M
            if (b->pal_sz[1])
1305
19.7k
                f->bd_fn.copy_pal_block_uv(t, bx4, by4, bw4, bh4);
1306
3.60M
        }
1307
5.45M
        if (IS_INTER_OR_SWITCH(f->frame_hdr) || f->frame_hdr->allow_intrabc)
1308
1.81M
            splat_intraref(f->c, t, bs, bw4, bh4);
1309
5.45M
    } else if (IS_KEY_OR_INTRA(f->frame_hdr)) {
1310
        // intra block copy
1311
978k
        refmvs_candidate mvstack[8];
1312
978k
        int n_mvs, ctx;
1313
978k
        dav1d_refmvs_find(&t->rt, mvstack, &n_mvs, &ctx,
1314
978k
                          (union refmvs_refpair) { .ref = { 0, -1 }},
1315
978k
                          bs, intra_edge_flags, t->by, t->bx);
1316
1317
978k
        if (mvstack[0].mv.mv[0].n)
1318
888k
            b->mv[0] = mvstack[0].mv.mv[0];
1319
89.3k
        else if (mvstack[1].mv.mv[0].n)
1320
0
            b->mv[0] = mvstack[1].mv.mv[0];
1321
89.3k
        else {
1322
89.3k
            if (t->by - (16 << f->seq_hdr->sb128) < ts->tiling.row_start) {
1323
41.6k
                b->mv[0].y = 0;
1324
41.6k
                b->mv[0].x = -(512 << f->seq_hdr->sb128) - 2048;
1325
47.7k
            } else {
1326
47.7k
                b->mv[0].y = -(512 << f->seq_hdr->sb128);
1327
47.7k
                b->mv[0].x = 0;
1328
47.7k
            }
1329
89.3k
        }
1330
1331
978k
        const union mv ref = b->mv[0];
1332
978k
        read_mv_residual(ts, &b->mv[0], -1);
1333
1334
        // clip intrabc motion vector to decoded parts of current tile
1335
978k
        int border_left = ts->tiling.col_start * 4;
1336
978k
        int border_top  = ts->tiling.row_start * 4;
1337
978k
        if (has_chroma) {
1338
755k
            if (bw4 < 2 &&  ss_hor)
1339
43.8k
                border_left += 4;
1340
755k
            if (bh4 < 2 &&  ss_ver)
1341
51.4k
                border_top  += 4;
1342
755k
        }
1343
978k
        int src_left   = t->bx * 4 + (b->mv[0].x >> 3);
1344
978k
        int src_top    = t->by * 4 + (b->mv[0].y >> 3);
1345
978k
        int src_right  = src_left + bw4 * 4;
1346
978k
        int src_bottom = src_top  + bh4 * 4;
1347
978k
        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
978k
        if (src_left < border_left) {
1351
315k
            src_right += border_left - src_left;
1352
315k
            src_left  += border_left - src_left;
1353
663k
        } else if (src_right > border_right) {
1354
156k
            src_left  -= src_right - border_right;
1355
156k
            src_right -= src_right - border_right;
1356
156k
        }
1357
        // check against top tile boundary and adjust if necessary
1358
978k
        if (src_top < border_top) {
1359
487k
            src_bottom += border_top - src_top;
1360
487k
            src_top    += border_top - src_top;
1361
487k
        }
1362
1363
978k
        const int sbx = (t->bx >> (4 + f->seq_hdr->sb128)) << (6 + f->seq_hdr->sb128);
1364
978k
        const int sby = (t->by >> (4 + f->seq_hdr->sb128)) << (6 + f->seq_hdr->sb128);
1365
978k
        const int sb_size = 1 << (6 + f->seq_hdr->sb128);
1366
        // check for overlap with current superblock
1367
978k
        if (src_bottom > sby && src_right > sbx) {
1368
157k
            if (src_top - border_top >= src_bottom - sby) {
1369
                // if possible move src up into the previous suberblock row
1370
25.5k
                src_top    -= src_bottom - sby;
1371
25.5k
                src_bottom -= src_bottom - sby;
1372
132k
            } else if (src_left - border_left >= src_right - sbx) {
1373
                // if possible move src left into the previous suberblock
1374
131k
                src_left  -= src_right - sbx;
1375
131k
                src_right -= src_right - sbx;
1376
131k
            }
1377
157k
        }
1378
        // move src up if it is below current superblock row
1379
978k
        if (src_bottom > sby + sb_size) {
1380
22.0k
            src_top    -= src_bottom - (sby + sb_size);
1381
22.0k
            src_bottom -= src_bottom - (sby + sb_size);
1382
22.0k
        }
1383
        // error out if mv still overlaps with the current superblock
1384
978k
        if (src_bottom > sby && src_right > sbx)
1385
752
            return -1;
1386
1387
977k
        b->mv[0].x = (src_left - t->bx * 4) * 8;
1388
977k
        b->mv[0].y = (src_top  - t->by * 4) * 8;
1389
1390
977k
        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
977k
        read_vartx_tree(t, b, bs, bx4, by4);
1395
1396
        // reconstruction
1397
977k
        if (t->frame_thread.pass == 1) {
1398
977k
            f->bd_fn.read_coef_blocks(t, bs, b);
1399
977k
            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
977k
        splat_intrabc_mv(f->c, t, bs, b, bw4, bh4);
1405
977k
        BlockContext *edge = t->a;
1406
2.93M
        for (int i = 0, off = bx4; i < 2; i++, off = by4, edge = &t->l) {
1407
1.95M
#define set_ctx(rep_macro) \
1408
1.95M
            rep_macro(edge->tx_intra, off, b_dim[2 + i]); \
1409
1.95M
            rep_macro(edge->mode, off, DC_PRED); \
1410
1.95M
            rep_macro(edge->pal_sz, off, 0); \
1411
            /* see aomedia bug 2183 for why this is outside if (has_chroma) */ \
1412
1.95M
            rep_macro(t->pal_sz_uv[i], off, 0); \
1413
1.95M
            rep_macro(edge->seg_pred, off, seg_pred); \
1414
1.95M
            rep_macro(edge->skip_mode, off, 0); \
1415
1.95M
            rep_macro(edge->intra, off, 0); \
1416
1.95M
            rep_macro(edge->skip, off, b->skip)
1417
1.95M
            case_set(b_dim[2 + i]);
1418
1.95M
#undef set_ctx
1419
1.95M
        }
1420
977k
        if (has_chroma) {
1421
755k
            dav1d_memset_pow2[ulog2(cbw4)](&t->a->uvmode[cbx4], DC_PRED);
1422
755k
            dav1d_memset_pow2[ulog2(cbh4)](&t->l.uvmode[cby4], DC_PRED);
1423
755k
        }
1424
977k
    } else {
1425
        // inter-specific mode/mv coding
1426
963k
        int is_comp, has_subpel_filter;
1427
1428
963k
        if (b->skip_mode) {
1429
1.32k
            is_comp = 1;
1430
962k
        } else if ((!seg || (seg->ref == -1 && !seg->globalmv && !seg->skip)) &&
1431
766k
                   f->frame_hdr->switchable_comp_refs && imin(bw4, bh4) > 1)
1432
349k
        {
1433
349k
            const int ctx = get_comp_ctx(t->a, &t->l, by4, bx4,
1434
349k
                                         have_top, have_left);
1435
349k
            is_comp = dav1d_msac_decode_bool_adapt(&ts->msac,
1436
349k
                          ts->cdf.m.comp[ctx]);
1437
349k
            if (DEBUG_BLOCK_INFO)
1438
0
                printf("Post-compflag[%d]: r=%d\n", is_comp, ts->msac.rng);
1439
612k
        } else {
1440
612k
            is_comp = 0;
1441
612k
        }
1442
1443
963k
        if (b->skip_mode) {
1444
1.32k
            b->ref[0] = f->frame_hdr->skip_mode_refs[0];
1445
1.32k
            b->ref[1] = f->frame_hdr->skip_mode_refs[1];
1446
1.32k
            b->comp_type = COMP_INTER_AVG;
1447
1.32k
            b->inter_mode = NEARESTMV_NEARESTMV;
1448
1.32k
            b->drl_idx = NEAREST_DRL;
1449
1.32k
            has_subpel_filter = 0;
1450
1451
1.32k
            refmvs_candidate mvstack[8];
1452
1.32k
            int n_mvs, ctx;
1453
1.32k
            dav1d_refmvs_find(&t->rt, mvstack, &n_mvs, &ctx,
1454
1.32k
                              (union refmvs_refpair) { .ref = {
1455
1.32k
                                    b->ref[0] + 1, b->ref[1] + 1 }},
1456
1.32k
                              bs, intra_edge_flags, t->by, t->bx);
1457
1458
1.32k
            b->mv[0] = mvstack[0].mv.mv[0];
1459
1.32k
            b->mv[1] = mvstack[0].mv.mv[1];
1460
1.32k
            fix_mv_precision(f->frame_hdr, &b->mv[0]);
1461
1.32k
            fix_mv_precision(f->frame_hdr, &b->mv[1]);
1462
1.32k
            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
962k
        } else if (is_comp) {
1467
190k
            const int dir_ctx = get_comp_dir_ctx(t->a, &t->l, by4, bx4,
1468
190k
                                                 have_top, have_left);
1469
190k
            if (dav1d_msac_decode_bool_adapt(&ts->msac,
1470
190k
                    ts->cdf.m.comp_dir[dir_ctx]))
1471
154k
            {
1472
                // bidir - first reference (fw)
1473
154k
                const int ctx1 = av1_get_fwd_ref_ctx(t->a, &t->l, by4, bx4,
1474
154k
                                                     have_top, have_left);
1475
154k
                if (dav1d_msac_decode_bool_adapt(&ts->msac,
1476
154k
                        ts->cdf.m.comp_fwd_ref[0][ctx1]))
1477
54.6k
                {
1478
54.6k
                    const int ctx2 = av1_get_fwd_ref_2_ctx(t->a, &t->l, by4, bx4,
1479
54.6k
                                                           have_top, have_left);
1480
54.6k
                    b->ref[0] = 2 + dav1d_msac_decode_bool_adapt(&ts->msac,
1481
54.6k
                                        ts->cdf.m.comp_fwd_ref[2][ctx2]);
1482
99.5k
                } else {
1483
99.5k
                    const int ctx2 = av1_get_fwd_ref_1_ctx(t->a, &t->l, by4, bx4,
1484
99.5k
                                                           have_top, have_left);
1485
99.5k
                    b->ref[0] = dav1d_msac_decode_bool_adapt(&ts->msac,
1486
99.5k
                                    ts->cdf.m.comp_fwd_ref[1][ctx2]);
1487
99.5k
                }
1488
1489
                // second reference (bw)
1490
154k
                const int ctx3 = av1_get_bwd_ref_ctx(t->a, &t->l, by4, bx4,
1491
154k
                                                     have_top, have_left);
1492
154k
                if (dav1d_msac_decode_bool_adapt(&ts->msac,
1493
154k
                        ts->cdf.m.comp_bwd_ref[0][ctx3]))
1494
80.1k
                {
1495
80.1k
                    b->ref[1] = 6;
1496
80.1k
                } else {
1497
74.1k
                    const int ctx4 = av1_get_bwd_ref_1_ctx(t->a, &t->l, by4, bx4,
1498
74.1k
                                                           have_top, have_left);
1499
74.1k
                    b->ref[1] = 4 + dav1d_msac_decode_bool_adapt(&ts->msac,
1500
74.1k
                                        ts->cdf.m.comp_bwd_ref[1][ctx4]);
1501
74.1k
                }
1502
154k
            } else {
1503
                // unidir
1504
36.1k
                const int uctx_p = av1_get_uni_p_ctx(t->a, &t->l, by4, bx4,
1505
36.1k
                                                     have_top, have_left);
1506
36.1k
                if (dav1d_msac_decode_bool_adapt(&ts->msac,
1507
36.1k
                        ts->cdf.m.comp_uni_ref[0][uctx_p]))
1508
9.61k
                {
1509
9.61k
                    b->ref[0] = 4;
1510
9.61k
                    b->ref[1] = 6;
1511
26.5k
                } else {
1512
26.5k
                    const int uctx_p1 = av1_get_uni_p1_ctx(t->a, &t->l, by4, bx4,
1513
26.5k
                                                           have_top, have_left);
1514
26.5k
                    b->ref[0] = 0;
1515
26.5k
                    b->ref[1] = 1 + dav1d_msac_decode_bool_adapt(&ts->msac,
1516
26.5k
                                        ts->cdf.m.comp_uni_ref[1][uctx_p1]);
1517
26.5k
                    if (b->ref[1] == 2) {
1518
17.2k
                        const int uctx_p2 = av1_get_uni_p2_ctx(t->a, &t->l, by4, bx4,
1519
17.2k
                                                               have_top, have_left);
1520
17.2k
                        b->ref[1] += dav1d_msac_decode_bool_adapt(&ts->msac,
1521
17.2k
                                         ts->cdf.m.comp_uni_ref[2][uctx_p2]);
1522
17.2k
                    }
1523
26.5k
                }
1524
36.1k
            }
1525
190k
            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
190k
            refmvs_candidate mvstack[8];
1530
190k
            int n_mvs, ctx;
1531
190k
            dav1d_refmvs_find(&t->rt, mvstack, &n_mvs, &ctx,
1532
190k
                              (union refmvs_refpair) { .ref = {
1533
190k
                                    b->ref[0] + 1, b->ref[1] + 1 }},
1534
190k
                              bs, intra_edge_flags, t->by, t->bx);
1535
1536
190k
            b->inter_mode = dav1d_msac_decode_symbol_adapt8(&ts->msac,
1537
190k
                                ts->cdf.m.comp_inter_mode[ctx],
1538
190k
                                N_COMP_INTER_PRED_MODES - 1);
1539
190k
            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
190k
            const uint8_t *const im = dav1d_comp_inter_pred_modes[b->inter_mode];
1544
190k
            b->drl_idx = NEAREST_DRL;
1545
190k
            if (b->inter_mode == NEWMV_NEWMV) {
1546
36.2k
                if (n_mvs > 1) { // NEARER, NEAR or NEARISH
1547
36.2k
                    const int drl_ctx_v1 = get_drl_context(mvstack, 0);
1548
36.2k
                    b->drl_idx += dav1d_msac_decode_bool_adapt(&ts->msac,
1549
36.2k
                                      ts->cdf.m.drl_bit[drl_ctx_v1]);
1550
36.2k
                    if (b->drl_idx == NEARER_DRL && n_mvs > 2) {
1551
4.63k
                        const int drl_ctx_v2 = get_drl_context(mvstack, 1);
1552
4.63k
                        b->drl_idx += dav1d_msac_decode_bool_adapt(&ts->msac,
1553
4.63k
                                          ts->cdf.m.drl_bit[drl_ctx_v2]);
1554
4.63k
                    }
1555
36.2k
                    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
36.2k
                }
1559
154k
            } else if (im[0] == NEARMV || im[1] == NEARMV) {
1560
44.9k
                b->drl_idx = NEARER_DRL;
1561
44.9k
                if (n_mvs > 2) { // NEAR or NEARISH
1562
3.77k
                    const int drl_ctx_v2 = get_drl_context(mvstack, 1);
1563
3.77k
                    b->drl_idx += dav1d_msac_decode_bool_adapt(&ts->msac,
1564
3.77k
                                      ts->cdf.m.drl_bit[drl_ctx_v2]);
1565
3.77k
                    if (b->drl_idx == NEAR_DRL && n_mvs > 3) {
1566
502
                        const int drl_ctx_v3 = get_drl_context(mvstack, 2);
1567
502
                        b->drl_idx += dav1d_msac_decode_bool_adapt(&ts->msac,
1568
502
                                          ts->cdf.m.drl_bit[drl_ctx_v3]);
1569
502
                    }
1570
3.77k
                    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
3.77k
                }
1574
44.9k
            }
1575
190k
            assert(b->drl_idx >= NEAREST_DRL && b->drl_idx <= NEARISH_DRL);
1576
1577
190k
#define assign_comp_mv(idx) \
1578
380k
            switch (im[idx]) { \
1579
78.3k
            case NEARMV: \
1580
233k
            case NEARESTMV: \
1581
233k
                b->mv[idx] = mvstack[b->drl_idx].mv.mv[idx]; \
1582
233k
                fix_mv_precision(f->frame_hdr, &b->mv[idx]); \
1583
233k
                break; \
1584
78.3k
            case GLOBALMV: \
1585
41.1k
                has_subpel_filter |= \
1586
41.1k
                    f->frame_hdr->gmv[b->ref[idx]].type == DAV1D_WM_TYPE_TRANSLATION; \
1587
41.1k
                b->mv[idx] = get_gmv_2d(&f->frame_hdr->gmv[b->ref[idx]], \
1588
41.1k
                                        t->bx, t->by, bw4, bh4, f->frame_hdr); \
1589
41.1k
                break; \
1590
106k
            case NEWMV: \
1591
106k
                b->mv[idx] = mvstack[b->drl_idx].mv.mv[idx]; \
1592
106k
                const int mv_prec = f->frame_hdr->hp - f->frame_hdr->force_integer_mv; \
1593
106k
                read_mv_residual(ts, &b->mv[idx], mv_prec); \
1594
106k
                break; \
1595
380k
            }
1596
190k
            has_subpel_filter = imin(bw4, bh4) == 1 ||
1597
190k
                                b->inter_mode != GLOBALMV_GLOBALMV;
1598
190k
            assign_comp_mv(0);
1599
190k
            assign_comp_mv(1);
1600
190k
#undef assign_comp_mv
1601
190k
            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
190k
            int is_segwedge = 0;
1608
190k
            if (f->seq_hdr->masked_compound) {
1609
152k
                const int mask_ctx = get_mask_comp_ctx(t->a, &t->l, by4, bx4);
1610
1611
152k
                is_segwedge = dav1d_msac_decode_bool_adapt(&ts->msac,
1612
152k
                                  ts->cdf.m.mask_comp[mask_ctx]);
1613
152k
                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
152k
            }
1617
1618
190k
            if (!is_segwedge) {
1619
149k
                if (f->seq_hdr->jnt_comp) {
1620
37.6k
                    const int jnt_ctx =
1621
37.6k
                        get_jnt_comp_ctx(f->seq_hdr->order_hint_n_bits,
1622
37.6k
                                         f->cur.frame_hdr->frame_offset,
1623
37.6k
                                         f->refp[b->ref[0]].p.frame_hdr->frame_offset,
1624
37.6k
                                         f->refp[b->ref[1]].p.frame_hdr->frame_offset,
1625
37.6k
                                         t->a, &t->l, by4, bx4);
1626
37.6k
                    b->comp_type = COMP_INTER_WEIGHTED_AVG +
1627
37.6k
                                   dav1d_msac_decode_bool_adapt(&ts->msac,
1628
37.6k
                                       ts->cdf.m.jnt_comp[jnt_ctx]);
1629
37.6k
                    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
111k
                } else {
1636
111k
                    b->comp_type = COMP_INTER_AVG;
1637
111k
                }
1638
149k
            } else {
1639
41.3k
                if (wedge_allowed_mask & (1 << bs)) {
1640
35.6k
                    const int ctx = dav1d_wedge_ctx_lut[bs];
1641
35.6k
                    b->comp_type = COMP_INTER_WEDGE -
1642
35.6k
                                   dav1d_msac_decode_bool_adapt(&ts->msac,
1643
35.6k
                                       ts->cdf.m.wedge_comp[ctx]);
1644
35.6k
                    if (b->comp_type == COMP_INTER_WEDGE)
1645
12.8k
                        b->wedge_idx = dav1d_msac_decode_symbol_adapt16(&ts->msac,
1646
12.8k
                                           ts->cdf.m.wedge_idx[ctx], 15);
1647
35.6k
                } else {
1648
5.77k
                    b->comp_type = COMP_INTER_SEG;
1649
5.77k
                }
1650
41.3k
                b->mask_sign = dav1d_msac_decode_bool_equi(&ts->msac);
1651
41.3k
                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
41.3k
            }
1656
771k
        } else {
1657
771k
            b->comp_type = COMP_INTER_NONE;
1658
1659
            // ref
1660
771k
            if (seg && seg->ref > 0) {
1661
143k
                b->ref[0] = seg->ref - 1;
1662
628k
            } else if (seg && (seg->globalmv || seg->skip)) {
1663
66.3k
                b->ref[0] = 0;
1664
562k
            } else {
1665
562k
                const int ctx1 = av1_get_ref_ctx(t->a, &t->l, by4, bx4,
1666
562k
                                                 have_top, have_left);
1667
562k
                if (dav1d_msac_decode_bool_adapt(&ts->msac,
1668
562k
                                                 ts->cdf.m.ref[0][ctx1]))
1669
274k
                {
1670
274k
                    const int ctx2 = av1_get_ref_2_ctx(t->a, &t->l, by4, bx4,
1671
274k
                                                       have_top, have_left);
1672
274k
                    if (dav1d_msac_decode_bool_adapt(&ts->msac,
1673
274k
                                                     ts->cdf.m.ref[1][ctx2]))
1674
186k
                    {
1675
186k
                        b->ref[0] = 6;
1676
186k
                    } else {
1677
88.1k
                        const int ctx3 = av1_get_ref_6_ctx(t->a, &t->l, by4, bx4,
1678
88.1k
                                                           have_top, have_left);
1679
88.1k
                        b->ref[0] = 4 + dav1d_msac_decode_bool_adapt(&ts->msac,
1680
88.1k
                                            ts->cdf.m.ref[5][ctx3]);
1681
88.1k
                    }
1682
287k
                } else {
1683
287k
                    const int ctx2 = av1_get_ref_3_ctx(t->a, &t->l, by4, bx4,
1684
287k
                                                       have_top, have_left);
1685
287k
                    if (dav1d_msac_decode_bool_adapt(&ts->msac,
1686
287k
                                                     ts->cdf.m.ref[2][ctx2]))
1687
93.3k
                    {
1688
93.3k
                        const int ctx3 = av1_get_ref_5_ctx(t->a, &t->l, by4, bx4,
1689
93.3k
                                                           have_top, have_left);
1690
93.3k
                        b->ref[0] = 2 + dav1d_msac_decode_bool_adapt(&ts->msac,
1691
93.3k
                                            ts->cdf.m.ref[4][ctx3]);
1692
194k
                    } else {
1693
194k
                        const int ctx3 = av1_get_ref_4_ctx(t->a, &t->l, by4, bx4,
1694
194k
                                                           have_top, have_left);
1695
194k
                        b->ref[0] = dav1d_msac_decode_bool_adapt(&ts->msac,
1696
194k
                                        ts->cdf.m.ref[3][ctx3]);
1697
194k
                    }
1698
287k
                }
1699
562k
                if (DEBUG_BLOCK_INFO)
1700
0
                    printf("Post-ref[%d]: r=%d\n", b->ref[0], ts->msac.rng);
1701
562k
            }
1702
771k
            b->ref[1] = -1;
1703
1704
771k
            refmvs_candidate mvstack[8];
1705
771k
            int n_mvs, ctx;
1706
771k
            dav1d_refmvs_find(&t->rt, mvstack, &n_mvs, &ctx,
1707
771k
                              (union refmvs_refpair) { .ref = { b->ref[0] + 1, -1 }},
1708
771k
                              bs, intra_edge_flags, t->by, t->bx);
1709
1710
            // mode parsing and mv derivation from ref_mvs
1711
771k
            if ((seg && (seg->skip || seg->globalmv)) ||
1712
594k
                dav1d_msac_decode_bool_adapt(&ts->msac,
1713
594k
                                             ts->cdf.m.newmv_mode[ctx & 7]))
1714
580k
            {
1715
580k
                if ((seg && (seg->skip || seg->globalmv)) ||
1716
389k
                    !dav1d_msac_decode_bool_adapt(&ts->msac,
1717
389k
                         ts->cdf.m.globalmv_mode[(ctx >> 3) & 1]))
1718
211k
                {
1719
211k
                    b->inter_mode = GLOBALMV;
1720
211k
                    b->mv[0] = get_gmv_2d(&f->frame_hdr->gmv[b->ref[0]],
1721
211k
                                          t->bx, t->by, bw4, bh4, f->frame_hdr);
1722
211k
                    has_subpel_filter = imin(bw4, bh4) == 1 ||
1723
135k
                        f->frame_hdr->gmv[b->ref[0]].type == DAV1D_WM_TYPE_TRANSLATION;
1724
368k
                } else {
1725
368k
                    has_subpel_filter = 1;
1726
368k
                    if (dav1d_msac_decode_bool_adapt(&ts->msac,
1727
368k
                            ts->cdf.m.refmv_mode[(ctx >> 4) & 15]))
1728
166k
                    { // NEAREST, NEARER, NEAR or NEARISH
1729
166k
                        b->inter_mode = NEARMV;
1730
166k
                        b->drl_idx = NEARER_DRL;
1731
166k
                        if (n_mvs > 2) { // NEARER, NEAR or NEARISH
1732
34.4k
                            const int drl_ctx_v2 = get_drl_context(mvstack, 1);
1733
34.4k
                            b->drl_idx += dav1d_msac_decode_bool_adapt(&ts->msac,
1734
34.4k
                                              ts->cdf.m.drl_bit[drl_ctx_v2]);
1735
34.4k
                            if (b->drl_idx == NEAR_DRL && n_mvs > 3) { // NEAR or NEARISH
1736
9.68k
                                const int drl_ctx_v3 =
1737
9.68k
                                    get_drl_context(mvstack, 2);
1738
9.68k
                                b->drl_idx += dav1d_msac_decode_bool_adapt(&ts->msac,
1739
9.68k
                                                  ts->cdf.m.drl_bit[drl_ctx_v3]);
1740
9.68k
                            }
1741
34.4k
                        }
1742
202k
                    } else {
1743
202k
                        b->inter_mode = NEARESTMV;
1744
202k
                        b->drl_idx = NEAREST_DRL;
1745
202k
                    }
1746
368k
                    assert(b->drl_idx >= NEAREST_DRL && b->drl_idx <= NEARISH_DRL);
1747
368k
                    b->mv[0] = mvstack[b->drl_idx].mv.mv[0];
1748
368k
                    if (b->drl_idx < NEAR_DRL)
1749
347k
                        fix_mv_precision(f->frame_hdr, &b->mv[0]);
1750
368k
                }
1751
1752
580k
                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
580k
            } else {
1757
191k
                has_subpel_filter = 1;
1758
191k
                b->inter_mode = NEWMV;
1759
191k
                b->drl_idx = NEAREST_DRL;
1760
191k
                if (n_mvs > 1) { // NEARER, NEAR or NEARISH
1761
122k
                    const int drl_ctx_v1 = get_drl_context(mvstack, 0);
1762
122k
                    b->drl_idx += dav1d_msac_decode_bool_adapt(&ts->msac,
1763
122k
                                      ts->cdf.m.drl_bit[drl_ctx_v1]);
1764
122k
                    if (b->drl_idx == NEARER_DRL && n_mvs > 2) { // NEAR or NEARISH
1765
19.1k
                        const int drl_ctx_v2 = get_drl_context(mvstack, 1);
1766
19.1k
                        b->drl_idx += dav1d_msac_decode_bool_adapt(&ts->msac,
1767
19.1k
                                          ts->cdf.m.drl_bit[drl_ctx_v2]);
1768
19.1k
                    }
1769
122k
                }
1770
191k
                assert(b->drl_idx >= NEAREST_DRL && b->drl_idx <= NEARISH_DRL);
1771
191k
                if (n_mvs > 1) {
1772
122k
                    b->mv[0] = mvstack[b->drl_idx].mv.mv[0];
1773
122k
                } else {
1774
68.3k
                    assert(!b->drl_idx);
1775
68.3k
                    b->mv[0] = mvstack[0].mv.mv[0];
1776
68.3k
                    fix_mv_precision(f->frame_hdr, &b->mv[0]);
1777
68.3k
                }
1778
191k
                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
191k
                const int mv_prec = f->frame_hdr->hp - f->frame_hdr->force_integer_mv;
1782
191k
                read_mv_residual(ts, &b->mv[0], mv_prec);
1783
191k
                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
191k
            }
1787
1788
            // interintra flags
1789
771k
            const int ii_sz_grp = dav1d_ymode_size_context[bs];
1790
771k
            if (f->seq_hdr->inter_intra &&
1791
397k
                interintra_allowed_mask & (1 << bs) &&
1792
162k
                dav1d_msac_decode_bool_adapt(&ts->msac,
1793
162k
                                             ts->cdf.m.interintra[ii_sz_grp]))
1794
28.5k
            {
1795
28.5k
                b->interintra_mode = dav1d_msac_decode_symbol_adapt4(&ts->msac,
1796
28.5k
                                         ts->cdf.m.interintra_mode[ii_sz_grp],
1797
28.5k
                                         N_INTER_INTRA_PRED_MODES - 1);
1798
28.5k
                const int wedge_ctx = dav1d_wedge_ctx_lut[bs];
1799
28.5k
                b->interintra_type = INTER_INTRA_BLEND +
1800
28.5k
                                     dav1d_msac_decode_bool_adapt(&ts->msac,
1801
28.5k
                                         ts->cdf.m.interintra_wedge[wedge_ctx]);
1802
28.5k
                if (b->interintra_type == INTER_INTRA_WEDGE)
1803
7.30k
                    b->wedge_idx = dav1d_msac_decode_symbol_adapt16(&ts->msac,
1804
7.30k
                                       ts->cdf.m.wedge_idx[wedge_ctx], 15);
1805
743k
            } else {
1806
743k
                b->interintra_type = INTER_INTRA_NONE;
1807
743k
            }
1808
771k
            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
771k
            if (f->frame_hdr->switchable_motion_mode &&
1818
585k
                b->interintra_type == INTER_INTRA_NONE && imin(bw4, bh4) >= 2 &&
1819
                // is not warped global motion
1820
294k
                !(!f->frame_hdr->force_integer_mv && b->inter_mode == GLOBALMV &&
1821
41.0k
                  f->frame_hdr->gmv[b->ref[0]].type > DAV1D_WM_TYPE_TRANSLATION) &&
1822
                // has overlappable neighbours
1823
278k
                ((have_left && findoddzero(&t->l.intra[by4 + 1], h4 >> 1)) ||
1824
56.8k
                 (have_top && findoddzero(&t->a->intra[bx4 + 1], w4 >> 1))))
1825
259k
            {
1826
                // reaching here means the block allows obmc - check warp by
1827
                // finding matching-ref blocks in top/left edges
1828
259k
                uint64_t mask[2] = { 0, 0 };
1829
259k
                find_matching_ref(t, intra_edge_flags, bw4, bh4, w4, h4,
1830
259k
                                  have_left, have_top, b->ref[0], mask);
1831
259k
                const int allow_warp = !f->svc[b->ref[0]][0].scale &&
1832
63.3k
                    !f->frame_hdr->force_integer_mv &&
1833
56.1k
                    f->frame_hdr->warp_motion && (mask[0] | mask[1]);
1834
1835
259k
                b->motion_mode = allow_warp ?
1836
22.4k
                    dav1d_msac_decode_symbol_adapt4(&ts->msac,
1837
22.4k
                        ts->cdf.m.motion_mode[bs], 2) :
1838
259k
                    dav1d_msac_decode_bool_adapt(&ts->msac, ts->cdf.m.obmc[bs]);
1839
259k
                if (b->motion_mode == MM_WARP) {
1840
7.91k
                    has_subpel_filter = 0;
1841
7.91k
                    derive_warpmv(t, bw4, bh4, mask, b->mv[0], &t->warpmv);
1842
7.91k
#define signabs(v) v < 0 ? '-' : ' ', abs(v)
1843
7.91k
                    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
7.91k
#undef signabs
1859
7.91k
                    if (t->frame_thread.pass) {
1860
7.91k
                        if (t->warpmv.type == DAV1D_WM_TYPE_AFFINE) {
1861
6.69k
                            b->matrix[0] = t->warpmv.matrix[2] - 0x10000;
1862
6.69k
                            b->matrix[1] = t->warpmv.matrix[3];
1863
6.69k
                            b->matrix[2] = t->warpmv.matrix[4];
1864
6.69k
                            b->matrix[3] = t->warpmv.matrix[5] - 0x10000;
1865
6.69k
                        } else {
1866
1.22k
                            b->matrix[0] = INT16_MIN;
1867
1.22k
                        }
1868
7.91k
                    }
1869
7.91k
                }
1870
1871
259k
                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
512k
            } else {
1876
512k
                b->motion_mode = MM_TRANSLATION;
1877
512k
            }
1878
771k
        }
1879
1880
        // subpel filter
1881
963k
        enum Dav1dFilterMode filter[2];
1882
963k
        if (f->frame_hdr->subpel_filter_mode == DAV1D_FILTER_SWITCHABLE) {
1883
416k
            if (has_subpel_filter) {
1884
362k
                const int comp = b->comp_type != COMP_INTER_NONE;
1885
362k
                const int ctx1 = get_filter_ctx(t->a, &t->l, comp, 0, b->ref[0],
1886
362k
                                                by4, bx4);
1887
362k
                filter[0] = dav1d_msac_decode_symbol_adapt4(&ts->msac,
1888
362k
                               ts->cdf.m.filter[0][ctx1],
1889
362k
                               DAV1D_N_SWITCHABLE_FILTERS - 1);
1890
362k
                if (f->seq_hdr->dual_filter) {
1891
225k
                    const int ctx2 = get_filter_ctx(t->a, &t->l, comp, 1,
1892
225k
                                                    b->ref[0], by4, bx4);
1893
225k
                    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
225k
                    filter[1] = dav1d_msac_decode_symbol_adapt4(&ts->msac,
1897
225k
                                    ts->cdf.m.filter[1][ctx2],
1898
225k
                                    DAV1D_N_SWITCHABLE_FILTERS - 1);
1899
225k
                    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
225k
                } else {
1903
137k
                    filter[1] = filter[0];
1904
137k
                    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
137k
                }
1908
362k
            } else {
1909
53.8k
                filter[0] = filter[1] = DAV1D_FILTER_8TAP_REGULAR;
1910
53.8k
            }
1911
546k
        } else {
1912
546k
            filter[0] = filter[1] = f->frame_hdr->subpel_filter_mode;
1913
546k
        }
1914
963k
        b->filter2d = dav1d_filter_2d[filter[1]][filter[0]];
1915
1916
963k
        read_vartx_tree(t, b, bs, bx4, by4);
1917
1918
        // reconstruction
1919
977k
        if (t->frame_thread.pass == 1) {
1920
977k
            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
963k
        if (f->frame_hdr->loopfilter.level_y[0] ||
1926
244k
            f->frame_hdr->loopfilter.level_y[1])
1927
822k
        {
1928
822k
            const int is_globalmv =
1929
822k
                b->inter_mode == (is_comp ? GLOBALMV_GLOBALMV : GLOBALMV);
1930
822k
            const uint8_t (*const lf_lvls)[8][2] = (const uint8_t (*)[8][2])
1931
822k
                &ts->lflvl[b->seg_id][0][b->ref[0] + 1][!is_globalmv];
1932
822k
            const uint16_t tx_split[2] = { b->tx_split0, b->tx_split1 };
1933
822k
            enum RectTxfmSize ytx = b->max_ytx, uvtx = b->uvtx;
1934
822k
            if (f->frame_hdr->segmentation.lossless[b->seg_id]) {
1935
20.8k
                ytx  = (enum RectTxfmSize) TX_4X4;
1936
20.8k
                uvtx = (enum RectTxfmSize) TX_4X4;
1937
20.8k
            }
1938
822k
            dav1d_create_lf_mask_inter(t->lf_mask, f->lf.level, f->b4_stride, lf_lvls,
1939
822k
                                       t->bx, t->by, f->w4, f->h4, b->skip, bs,
1940
822k
                                       ytx, tx_split, uvtx, f->cur.p.layout,
1941
822k
                                       &t->a->tx_lpf_y[bx4], &t->l.tx_lpf_y[by4],
1942
822k
                                       has_chroma ? &t->a->tx_lpf_uv[cbx4] : NULL,
1943
822k
                                       has_chroma ? &t->l.tx_lpf_uv[cby4] : NULL);
1944
822k
        }
1945
1946
        // context updates
1947
963k
        if (is_comp)
1948
191k
            splat_tworef_mv(f->c, t, bs, b, bw4, bh4);
1949
771k
        else
1950
771k
            splat_oneref_mv(f->c, t, bs, b, bw4, bh4);
1951
963k
        BlockContext *edge = t->a;
1952
2.91M
        for (int i = 0, off = bx4; i < 2; i++, off = by4, edge = &t->l) {
1953
1.95M
#define set_ctx(rep_macro) \
1954
1.95M
            rep_macro(edge->seg_pred, off, seg_pred); \
1955
1.95M
            rep_macro(edge->skip_mode, off, b->skip_mode); \
1956
1.95M
            rep_macro(edge->intra, off, 0); \
1957
1.95M
            rep_macro(edge->skip, off, b->skip); \
1958
1.95M
            rep_macro(edge->pal_sz, off, 0); \
1959
            /* see aomedia bug 2183 for why this is outside if (has_chroma) */ \
1960
1.95M
            rep_macro(t->pal_sz_uv[i], off, 0); \
1961
1.95M
            rep_macro(edge->tx_intra, off, b_dim[2 + i]); \
1962
1.95M
            rep_macro(edge->comp_type, off, b->comp_type); \
1963
1.95M
            rep_macro(edge->filter[0], off, filter[0]); \
1964
1.95M
            rep_macro(edge->filter[1], off, filter[1]); \
1965
1.95M
            rep_macro(edge->mode, off, b->inter_mode); \
1966
1.95M
            rep_macro(edge->ref[0], off, b->ref[0]); \
1967
1.95M
            rep_macro(edge->ref[1], off, ((uint8_t) b->ref[1]))
1968
1.95M
            case_set(b_dim[2 + i]);
1969
1.95M
#undef set_ctx
1970
1.95M
        }
1971
963k
        if (has_chroma) {
1972
483k
            dav1d_memset_pow2[ulog2(cbw4)](&t->a->uvmode[cbx4], DC_PRED);
1973
483k
            dav1d_memset_pow2[ulog2(cbh4)](&t->l.uvmode[cby4], DC_PRED);
1974
483k
        }
1975
963k
    }
1976
1977
    // update contexts
1978
7.39M
    if (f->frame_hdr->segmentation.enabled &&
1979
3.85M
        f->frame_hdr->segmentation.update_map)
1980
3.78M
    {
1981
3.78M
        uint8_t *seg_ptr = &f->cur_segmap[t->by * f->b4_stride + t->bx];
1982
3.78M
#define set_ctx(rep_macro) \
1983
22.1M
        for (int y = 0; y < bh4; y++) { \
1984
18.4M
            rep_macro(seg_ptr, 0, b->seg_id); \
1985
18.4M
            seg_ptr += f->b4_stride; \
1986
18.4M
        }
1987
3.78M
        case_set(b_dim[2]);
1988
3.78M
#undef set_ctx
1989
3.78M
    }
1990
7.39M
    if (!b->skip) {
1991
3.21M
        uint16_t (*noskip_mask)[2] = &t->lf_mask->noskip_mask[by4 >> 1];
1992
3.21M
        const unsigned mask = (~0U >> (32 - bw4)) << (bx4 & 15);
1993
3.21M
        const int bx_idx = (bx4 & 16) >> 4;
1994
11.0M
        for (int y = 0; y < bh4; y += 2, noskip_mask++) {
1995
7.81M
            (*noskip_mask)[bx_idx] |= mask;
1996
7.81M
            if (bw4 == 32) // this should be mask >> 16, but it's 0xffffffff anyway
1997
714k
                (*noskip_mask)[1] |= mask;
1998
7.81M
        }
1999
3.21M
    }
2000
2001
7.41M
    if (t->frame_thread.pass == 1 && !b->intra && IS_INTER_OR_SWITCH(f->frame_hdr)) {
2002
977k
        const int sby = (t->by - ts->tiling.row_start) >> f->sb_shift;
2003
977k
        int (*const lowest_px)[2] = ts->lowest_pixel[sby];
2004
2005
        // keep track of motion vectors for each reference
2006
977k
        if (b->comp_type == COMP_INTER_NONE) {
2007
            // y
2008
785k
            if (imin(bw4, bh4) > 1 &&
2009
412k
                ((b->inter_mode == GLOBALMV && f->gmv_warp_allowed[b->ref[0]]) ||
2010
393k
                 (b->motion_mode == MM_WARP && t->warpmv.type > DAV1D_WM_TYPE_TRANSLATION)))
2011
26.0k
            {
2012
26.0k
                affine_lowest_px_luma(t, &lowest_px[b->ref[0]][0], b_dim,
2013
26.0k
                                      b->motion_mode == MM_WARP ? &t->warpmv :
2014
26.0k
                                      &f->frame_hdr->gmv[b->ref[0]]);
2015
759k
            } else {
2016
759k
                mc_lowest_px(&lowest_px[b->ref[0]][0], t->by, bh4, b->mv[0].y,
2017
759k
                             0, &f->svc[b->ref[0]][1]);
2018
759k
                if (b->motion_mode == MM_OBMC) {
2019
140k
                    obmc_lowest_px(t, lowest_px, 0, b_dim, bx4, by4, w4, h4);
2020
140k
                }
2021
759k
            }
2022
2023
            // uv
2024
785k
            if (has_chroma) {
2025
                // sub8x8 derivation
2026
384k
                int is_sub8x8 = bw4 == ss_hor || bh4 == ss_ver;
2027
384k
                refmvs_block *const *r;
2028
384k
                if (is_sub8x8) {
2029
69.9k
                    assert(ss_hor == 1);
2030
69.9k
                    r = &t->rt.r[(t->by & 31) + 5];
2031
69.9k
                    if (bw4 == 1) is_sub8x8 &= r[0][t->bx - 1].ref.ref[0] > 0;
2032
69.9k
                    if (bh4 == ss_ver) is_sub8x8 &= r[-1][t->bx].ref.ref[0] > 0;
2033
69.9k
                    if (bw4 == 1 && bh4 == ss_ver)
2034
15.4k
                        is_sub8x8 &= r[-1][t->bx - 1].ref.ref[0] > 0;
2035
69.9k
                }
2036
2037
                // chroma prediction
2038
384k
                if (is_sub8x8) {
2039
66.3k
                    assert(ss_hor == 1);
2040
66.3k
                    if (bw4 == 1 && bh4 == ss_ver) {
2041
13.4k
                        const refmvs_block *const rr = &r[-1][t->bx - 1];
2042
13.4k
                        mc_lowest_px(&lowest_px[rr->ref.ref[0] - 1][1],
2043
13.4k
                                     t->by - 1, bh4, rr->mv.mv[0].y, ss_ver,
2044
13.4k
                                     &f->svc[rr->ref.ref[0] - 1][1]);
2045
13.4k
                    }
2046
66.3k
                    if (bw4 == 1) {
2047
38.0k
                        const refmvs_block *const rr = &r[0][t->bx - 1];
2048
38.0k
                        mc_lowest_px(&lowest_px[rr->ref.ref[0] - 1][1],
2049
38.0k
                                     t->by, bh4, rr->mv.mv[0].y, ss_ver,
2050
38.0k
                                     &f->svc[rr->ref.ref[0] - 1][1]);
2051
38.0k
                    }
2052
66.3k
                    if (bh4 == ss_ver) {
2053
41.8k
                        const refmvs_block *const rr = &r[-1][t->bx];
2054
41.8k
                        mc_lowest_px(&lowest_px[rr->ref.ref[0] - 1][1],
2055
41.8k
                                     t->by - 1, bh4, rr->mv.mv[0].y, ss_ver,
2056
41.8k
                                     &f->svc[rr->ref.ref[0] - 1][1]);
2057
41.8k
                    }
2058
66.3k
                    mc_lowest_px(&lowest_px[b->ref[0]][1], t->by, bh4,
2059
66.3k
                                 b->mv[0].y, ss_ver, &f->svc[b->ref[0]][1]);
2060
317k
                } else {
2061
317k
                    if (imin(cbw4, cbh4) > 1 &&
2062
129k
                        ((b->inter_mode == GLOBALMV && f->gmv_warp_allowed[b->ref[0]]) ||
2063
122k
                         (b->motion_mode == MM_WARP && t->warpmv.type > DAV1D_WM_TYPE_TRANSLATION)))
2064
7.92k
                    {
2065
7.92k
                        affine_lowest_px_chroma(t, &lowest_px[b->ref[0]][1], b_dim,
2066
7.92k
                                                b->motion_mode == MM_WARP ? &t->warpmv :
2067
7.92k
                                                &f->frame_hdr->gmv[b->ref[0]]);
2068
309k
                    } else {
2069
309k
                        mc_lowest_px(&lowest_px[b->ref[0]][1],
2070
309k
                                     t->by & ~ss_ver, bh4 << (bh4 == ss_ver),
2071
309k
                                     b->mv[0].y, ss_ver, &f->svc[b->ref[0]][1]);
2072
309k
                        if (b->motion_mode == MM_OBMC) {
2073
96.7k
                            obmc_lowest_px(t, lowest_px, 1, b_dim, bx4, by4, w4, h4);
2074
96.7k
                        }
2075
309k
                    }
2076
317k
                }
2077
384k
            }
2078
785k
        } else {
2079
            // y
2080
575k
            for (int i = 0; i < 2; i++) {
2081
383k
                if (b->inter_mode == GLOBALMV_GLOBALMV && f->gmv_warp_allowed[b->ref[i]]) {
2082
3.65k
                    affine_lowest_px_luma(t, &lowest_px[b->ref[i]][0], b_dim,
2083
3.65k
                                          &f->frame_hdr->gmv[b->ref[i]]);
2084
379k
                } else {
2085
379k
                    mc_lowest_px(&lowest_px[b->ref[i]][0], t->by, bh4,
2086
379k
                                 b->mv[i].y, 0, &f->svc[b->ref[i]][1]);
2087
379k
                }
2088
383k
            }
2089
2090
            // uv
2091
299k
            if (has_chroma) for (int i = 0; i < 2; i++) {
2092
199k
                if (b->inter_mode == GLOBALMV_GLOBALMV &&
2093
21.9k
                    imin(cbw4, cbh4) > 1 && f->gmv_warp_allowed[b->ref[i]])
2094
700
                {
2095
700
                    affine_lowest_px_chroma(t, &lowest_px[b->ref[i]][1], b_dim,
2096
700
                                            &f->frame_hdr->gmv[b->ref[i]]);
2097
199k
                } else {
2098
199k
                    mc_lowest_px(&lowest_px[b->ref[i]][1], t->by, bh4,
2099
199k
                                 b->mv[i].y, ss_ver, &f->svc[b->ref[i]][1]);
2100
199k
                }
2101
199k
            }
2102
191k
        }
2103
977k
    }
2104
2105
7.39M
    return 0;
2106
7.39M
}
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
9.74M
{
2164
9.74M
    const Dav1dFrameContext *const f = t->f;
2165
9.74M
    Dav1dTileState *const ts = t->ts;
2166
9.74M
    const int hsz = 16 >> bl;
2167
9.74M
    const int have_h_split = f->bw > t->bx + hsz;
2168
9.74M
    const int have_v_split = f->bh > t->by + hsz;
2169
2170
9.74M
    if (!have_h_split && !have_v_split) {
2171
225k
        assert(bl < BL_8X8);
2172
225k
        return decode_sb(t, bl + 1, INTRA_EDGE_SPLIT(node, 0));
2173
225k
    }
2174
2175
9.52M
    uint16_t *pc;
2176
9.52M
    enum BlockPartition bp;
2177
9.52M
    int ctx, bx8, by8;
2178
9.52M
    if (t->frame_thread.pass != 2) {
2179
5.95M
        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
5.95M
        bx8 = (t->bx & 31) >> 1;
2183
5.95M
        by8 = (t->by & 31) >> 1;
2184
5.95M
        ctx = get_partition_ctx(t->a, &t->l, bl, by8, bx8);
2185
5.95M
        pc = ts->cdf.m.partition[bl][ctx];
2186
5.95M
    }
2187
2188
9.52M
    if (have_h_split && have_v_split) {
2189
6.03M
        if (t->frame_thread.pass == 2) {
2190
2.22M
            const Av1Block *const b = &f->frame_thread.b[t->by * f->b4_stride + t->bx];
2191
2.22M
            bp = b->bl == bl ? b->bp : PARTITION_SPLIT;
2192
3.80M
        } else {
2193
3.80M
            bp = dav1d_msac_decode_symbol_adapt16(&ts->msac, pc,
2194
3.80M
                                                  dav1d_partition_type_count[bl]);
2195
3.80M
            if (f->cur.p.layout == DAV1D_PIXEL_LAYOUT_I422 &&
2196
19.8k
                (bp == PARTITION_V || bp == PARTITION_V4 ||
2197
19.4k
                 bp == PARTITION_T_LEFT_SPLIT || bp == PARTITION_T_RIGHT_SPLIT))
2198
498
            {
2199
498
                return 1;
2200
498
            }
2201
3.80M
            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
3.80M
        }
2206
6.03M
        const uint8_t *const b = dav1d_block_sizes[bl][bp];
2207
2208
6.03M
        switch (bp) {
2209
2.39M
        case PARTITION_NONE:
2210
2.39M
            if (decode_b(t, bl, b[0], PARTITION_NONE, node->o))
2211
50
                return -1;
2212
2.39M
            break;
2213
2.39M
        case PARTITION_H:
2214
772k
            if (decode_b(t, bl, b[0], PARTITION_H, node->h[0]))
2215
29
                return -1;
2216
772k
            t->by += hsz;
2217
772k
            if (decode_b(t, bl, b[0], PARTITION_H, node->h[1]))
2218
35
                return -1;
2219
772k
            t->by -= hsz;
2220
772k
            break;
2221
554k
        case PARTITION_V:
2222
554k
            if (decode_b(t, bl, b[0], PARTITION_V, node->v[0]))
2223
35
                return -1;
2224
554k
            t->bx += hsz;
2225
554k
            if (decode_b(t, bl, b[0], PARTITION_V, node->v[1]))
2226
48
                return -1;
2227
554k
            t->bx -= hsz;
2228
554k
            break;
2229
1.39M
        case PARTITION_SPLIT:
2230
1.39M
            if (bl == BL_8X8) {
2231
424k
                const EdgeTip *const tip = (const EdgeTip *) node;
2232
424k
                assert(hsz == 1);
2233
424k
                if (decode_b(t, bl, BS_4x4, PARTITION_SPLIT, EDGE_ALL_TR_AND_BL))
2234
34
                    return -1;
2235
424k
                const enum Filter2d tl_filter = t->tl_4x4_filter;
2236
424k
                t->bx++;
2237
424k
                if (decode_b(t, bl, BS_4x4, PARTITION_SPLIT, tip->split[0]))
2238
34
                    return -1;
2239
424k
                t->bx--;
2240
424k
                t->by++;
2241
424k
                if (decode_b(t, bl, BS_4x4, PARTITION_SPLIT, tip->split[1]))
2242
26
                    return -1;
2243
424k
                t->bx++;
2244
424k
                t->tl_4x4_filter = tl_filter;
2245
424k
                if (decode_b(t, bl, BS_4x4, PARTITION_SPLIT, tip->split[2]))
2246
19
                    return -1;
2247
424k
                t->bx--;
2248
424k
                t->by--;
2249
424k
#if ARCH_X86_64
2250
424k
                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
424k
                    const int p = t->frame_thread.pass & 1;
2255
424k
                    ts->frame_thread[p].cf =
2256
424k
                        (void*)(((uintptr_t)ts->frame_thread[p].cf + 63) & ~63);
2257
424k
                }
2258
424k
#endif
2259
970k
            } else {
2260
970k
                if (decode_sb(t, bl + 1, INTRA_EDGE_SPLIT(node, 0)))
2261
259
                    return 1;
2262
970k
                t->bx += hsz;
2263
970k
                if (decode_sb(t, bl + 1, INTRA_EDGE_SPLIT(node, 1)))
2264
276
                    return 1;
2265
969k
                t->bx -= hsz;
2266
969k
                t->by += hsz;
2267
969k
                if (decode_sb(t, bl + 1, INTRA_EDGE_SPLIT(node, 2)))
2268
228
                    return 1;
2269
969k
                t->bx += hsz;
2270
969k
                if (decode_sb(t, bl + 1, INTRA_EDGE_SPLIT(node, 3)))
2271
225
                    return 1;
2272
969k
                t->bx -= hsz;
2273
969k
                t->by -= hsz;
2274
969k
            }
2275
1.39M
            break;
2276
1.39M
        case PARTITION_T_TOP_SPLIT: {
2277
107k
            if (decode_b(t, bl, b[0], PARTITION_T_TOP_SPLIT, EDGE_ALL_TR_AND_BL))
2278
16
                return -1;
2279
107k
            t->bx += hsz;
2280
107k
            if (decode_b(t, bl, b[0], PARTITION_T_TOP_SPLIT, node->v[1]))
2281
31
                return -1;
2282
107k
            t->bx -= hsz;
2283
107k
            t->by += hsz;
2284
107k
            if (decode_b(t, bl, b[1], PARTITION_T_TOP_SPLIT, node->h[1]))
2285
16
                return -1;
2286
107k
            t->by -= hsz;
2287
107k
            break;
2288
107k
        }
2289
111k
        case PARTITION_T_BOTTOM_SPLIT: {
2290
111k
            if (decode_b(t, bl, b[0], PARTITION_T_BOTTOM_SPLIT, node->h[0]))
2291
20
                return -1;
2292
111k
            t->by += hsz;
2293
111k
            if (decode_b(t, bl, b[1], PARTITION_T_BOTTOM_SPLIT, node->v[0]))
2294
14
                return -1;
2295
111k
            t->bx += hsz;
2296
111k
            if (decode_b(t, bl, b[1], PARTITION_T_BOTTOM_SPLIT, 0))
2297
13
                return -1;
2298
111k
            t->bx -= hsz;
2299
111k
            t->by -= hsz;
2300
111k
            break;
2301
111k
        }
2302
83.7k
        case PARTITION_T_LEFT_SPLIT: {
2303
83.7k
            if (decode_b(t, bl, b[0], PARTITION_T_LEFT_SPLIT, EDGE_ALL_TR_AND_BL))
2304
14
                return -1;
2305
83.7k
            t->by += hsz;
2306
83.7k
            if (decode_b(t, bl, b[0], PARTITION_T_LEFT_SPLIT, node->h[1]))
2307
14
                return -1;
2308
83.7k
            t->by -= hsz;
2309
83.7k
            t->bx += hsz;
2310
83.7k
            if (decode_b(t, bl, b[1], PARTITION_T_LEFT_SPLIT, node->v[1]))
2311
14
                return -1;
2312
83.7k
            t->bx -= hsz;
2313
83.7k
            break;
2314
83.7k
        }
2315
107k
        case PARTITION_T_RIGHT_SPLIT: {
2316
107k
            if (decode_b(t, bl, b[0], PARTITION_T_RIGHT_SPLIT, node->v[0]))
2317
17
                return -1;
2318
107k
            t->bx += hsz;
2319
107k
            if (decode_b(t, bl, b[1], PARTITION_T_RIGHT_SPLIT, node->h[0]))
2320
18
                return -1;
2321
107k
            t->by += hsz;
2322
107k
            if (decode_b(t, bl, b[1], PARTITION_T_RIGHT_SPLIT, 0))
2323
22
                return -1;
2324
107k
            t->by -= hsz;
2325
107k
            t->bx -= hsz;
2326
107k
            break;
2327
107k
        }
2328
242k
        case PARTITION_H4: {
2329
242k
            const EdgeBranch *const branch = (const EdgeBranch *) node;
2330
242k
            if (decode_b(t, bl, b[0], PARTITION_H4, node->h[0]))
2331
21
                return -1;
2332
242k
            t->by += hsz >> 1;
2333
242k
            if (decode_b(t, bl, b[0], PARTITION_H4, branch->h4))
2334
26
                return -1;
2335
242k
            t->by += hsz >> 1;
2336
242k
            if (decode_b(t, bl, b[0], PARTITION_H4, EDGE_ALL_LEFT_HAS_BOTTOM))
2337
14
                return -1;
2338
242k
            t->by += hsz >> 1;
2339
242k
            if (t->by < f->bh)
2340
238k
                if (decode_b(t, bl, b[0], PARTITION_H4, node->h[1]))
2341
15
                    return -1;
2342
242k
            t->by -= hsz * 3 >> 1;
2343
242k
            break;
2344
242k
        }
2345
262k
        case PARTITION_V4: {
2346
262k
            const EdgeBranch *const branch = (const EdgeBranch *) node;
2347
262k
            if (decode_b(t, bl, b[0], PARTITION_V4, node->v[0]))
2348
47
                return -1;
2349
262k
            t->bx += hsz >> 1;
2350
262k
            if (decode_b(t, bl, b[0], PARTITION_V4, branch->v4))
2351
21
                return -1;
2352
262k
            t->bx += hsz >> 1;
2353
262k
            if (decode_b(t, bl, b[0], PARTITION_V4, EDGE_ALL_TOP_HAS_RIGHT))
2354
13
                return -1;
2355
262k
            t->bx += hsz >> 1;
2356
262k
            if (t->bx < f->bw)
2357
232k
                if (decode_b(t, bl, b[0], PARTITION_V4, node->v[1]))
2358
14
                    return -1;
2359
262k
            t->bx -= hsz * 3 >> 1;
2360
262k
            break;
2361
262k
        }
2362
0
        default: assert(0);
2363
6.03M
        }
2364
6.03M
    } else if (have_h_split) {
2365
1.33M
        unsigned is_split;
2366
1.33M
        if (t->frame_thread.pass == 2) {
2367
365k
            const Av1Block *const b = &f->frame_thread.b[t->by * f->b4_stride + t->bx];
2368
365k
            is_split = b->bl != bl;
2369
971k
        } else {
2370
971k
            is_split = dav1d_msac_decode_bool(&ts->msac,
2371
971k
                           gather_top_partition_prob(pc, bl));
2372
971k
            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
971k
        }
2377
2378
1.33M
        assert(bl < BL_8X8);
2379
1.33M
        if (is_split) {
2380
756k
            bp = PARTITION_SPLIT;
2381
756k
            if (decode_sb(t, bl + 1, INTRA_EDGE_SPLIT(node, 0))) return 1;
2382
755k
            t->bx += hsz;
2383
755k
            if (decode_sb(t, bl + 1, INTRA_EDGE_SPLIT(node, 1))) return 1;
2384
755k
            t->bx -= hsz;
2385
755k
        } else {
2386
580k
            bp = PARTITION_H;
2387
580k
            if (decode_b(t, bl, dav1d_block_sizes[bl][PARTITION_H][0],
2388
580k
                         PARTITION_H, node->h[0]))
2389
33
                return -1;
2390
580k
        }
2391
2.15M
    } else {
2392
2.15M
        assert(have_v_split);
2393
2.15M
        unsigned is_split;
2394
2.15M
        if (t->frame_thread.pass == 2) {
2395
993k
            const Av1Block *const b = &f->frame_thread.b[t->by * f->b4_stride + t->bx];
2396
993k
            is_split = b->bl != bl;
2397
1.16M
        } else {
2398
1.16M
            is_split = dav1d_msac_decode_bool(&ts->msac,
2399
1.16M
                           gather_left_partition_prob(pc, bl));
2400
1.16M
            if (f->cur.p.layout == DAV1D_PIXEL_LAYOUT_I422 && !is_split)
2401
106
                return 1;
2402
1.16M
            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
1.16M
        }
2407
2408
2.15M
        assert(bl < BL_8X8);
2409
2.15M
        if (is_split) {
2410
1.12M
            bp = PARTITION_SPLIT;
2411
1.12M
            if (decode_sb(t, bl + 1, INTRA_EDGE_SPLIT(node, 0))) return 1;
2412
1.12M
            t->by += hsz;
2413
1.12M
            if (decode_sb(t, bl + 1, INTRA_EDGE_SPLIT(node, 2))) return 1;
2414
1.12M
            t->by -= hsz;
2415
1.12M
        } else {
2416
1.03M
            bp = PARTITION_V;
2417
1.03M
            if (decode_b(t, bl, dav1d_block_sizes[bl][PARTITION_V][0],
2418
1.03M
                         PARTITION_V, node->v[0]))
2419
29
                return -1;
2420
1.03M
        }
2421
2.15M
    }
2422
2423
9.52M
    if (t->frame_thread.pass != 2 && (bp != PARTITION_SPLIT || bl == BL_8X8)) {
2424
4.14M
#define set_ctx(rep_macro) \
2425
4.14M
        rep_macro(t->a->partition, bx8, dav1d_al_part_ctx[0][bl][bp]); \
2426
4.14M
        rep_macro(t->l.partition, by8, dav1d_al_part_ctx[1][bl][bp])
2427
4.14M
        case_set_upto16(ulog2(hsz));
2428
4.14M
#undef set_ctx
2429
4.14M
    }
2430
2431
9.52M
    return 0;
2432
9.52M
}
2433
2434
1.72M
static void reset_context(BlockContext *const ctx, const int keyframe, const int pass) {
2435
1.72M
    memset(ctx->intra, keyframe, sizeof(ctx->intra));
2436
1.72M
    memset(ctx->uvmode, DC_PRED, sizeof(ctx->uvmode));
2437
1.72M
    if (keyframe)
2438
1.45M
        memset(ctx->mode, DC_PRED, sizeof(ctx->mode));
2439
2440
1.72M
    if (pass == 2) return;
2441
2442
901k
    memset(ctx->partition, 0, sizeof(ctx->partition));
2443
901k
    memset(ctx->skip, 0, sizeof(ctx->skip));
2444
901k
    memset(ctx->skip_mode, 0, sizeof(ctx->skip_mode));
2445
901k
    memset(ctx->tx_lpf_y, 2, sizeof(ctx->tx_lpf_y));
2446
901k
    memset(ctx->tx_lpf_uv, 1, sizeof(ctx->tx_lpf_uv));
2447
901k
    memset(ctx->tx_intra, -1, sizeof(ctx->tx_intra));
2448
901k
    memset(ctx->tx, TX_64X64, sizeof(ctx->tx));
2449
901k
    if (!keyframe) {
2450
140k
        memset(ctx->ref, -1, sizeof(ctx->ref));
2451
140k
        memset(ctx->comp_type, 0, sizeof(ctx->comp_type));
2452
140k
        memset(ctx->mode, NEARESTMV, sizeof(ctx->mode));
2453
140k
    }
2454
901k
    memset(ctx->lcoef, 0x40, sizeof(ctx->lcoef));
2455
901k
    memset(ctx->ccoef, 0x40, sizeof(ctx->ccoef));
2456
901k
    memset(ctx->filter, DAV1D_N_SWITCHABLE_FILTERS, sizeof(ctx->filter));
2457
901k
    memset(ctx->seg_pred, 0, sizeof(ctx->seg_pred));
2458
901k
    memset(ctx->pal_sz, 0, sizeof(ctx->pal_sz));
2459
901k
}
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
143k
{
2475
143k
    const int col_sb_start = f->frame_hdr->tiling.col_start_sb[tile_col];
2476
143k
    const int col_sb128_start = col_sb_start >> !f->seq_hdr->sb128;
2477
143k
    const int col_sb_end = f->frame_hdr->tiling.col_start_sb[tile_col + 1];
2478
143k
    const int row_sb_start = f->frame_hdr->tiling.row_start_sb[tile_row];
2479
143k
    const int row_sb_end = f->frame_hdr->tiling.row_start_sb[tile_row + 1];
2480
143k
    const int sb_shift = f->sb_shift;
2481
2482
143k
    const uint8_t *const size_mul = ss_size_mul[f->cur.p.layout];
2483
429k
    for (int p = 0; p < 2; p++) {
2484
286k
        ts->frame_thread[p].pal_idx = f->frame_thread.pal_idx ?
2485
102k
            &f->frame_thread.pal_idx[(size_t)tile_start_off * size_mul[1] / 8] :
2486
286k
            NULL;
2487
286k
        ts->frame_thread[p].cbi = f->frame_thread.cbi ?
2488
286k
            &f->frame_thread.cbi[(size_t)tile_start_off * size_mul[0] / 64] :
2489
286k
            NULL;
2490
286k
        ts->frame_thread[p].cf = f->frame_thread.cf ?
2491
286k
            (uint8_t*)f->frame_thread.cf +
2492
286k
                (((size_t)tile_start_off * size_mul[0]) >> !f->seq_hdr->hbd) :
2493
286k
            NULL;
2494
286k
    }
2495
2496
143k
    dav1d_cdf_thread_copy(&ts->cdf, &f->in_cdf);
2497
143k
    ts->last_qidx = f->frame_hdr->quant.yac;
2498
143k
    ts->last_delta_lf.u32 = 0;
2499
2500
143k
    dav1d_msac_init(&ts->msac, data, sz, f->frame_hdr->disable_cdf_update);
2501
2502
143k
    ts->tiling.row = tile_row;
2503
143k
    ts->tiling.col = tile_col;
2504
143k
    ts->tiling.col_start = col_sb_start << sb_shift;
2505
143k
    ts->tiling.col_end = imin(col_sb_end << sb_shift, f->bw);
2506
143k
    ts->tiling.row_start = row_sb_start << sb_shift;
2507
143k
    ts->tiling.row_end = imin(row_sb_end << sb_shift, f->bh);
2508
2509
    // Reference Restoration Unit (used for exp coding)
2510
143k
    int sb_idx, unit_idx;
2511
143k
    if (f->frame_hdr->width[0] != f->frame_hdr->width[1]) {
2512
        // vertical components only
2513
31.0k
        sb_idx = (ts->tiling.row_start >> 5) * f->sr_sb128w;
2514
31.0k
        unit_idx = (ts->tiling.row_start & 16) >> 3;
2515
112k
    } else {
2516
112k
        sb_idx = (ts->tiling.row_start >> 5) * f->sb128w + col_sb128_start;
2517
112k
        unit_idx = ((ts->tiling.row_start & 16) >> 3) +
2518
112k
                   ((ts->tiling.col_start & 16) >> 4);
2519
112k
    }
2520
572k
    for (int p = 0; p < 3; p++) {
2521
429k
        if (!((f->lf.restore_planes >> p) & 1U))
2522
341k
            continue;
2523
2524
87.1k
        if (f->frame_hdr->width[0] != f->frame_hdr->width[1]) {
2525
32.3k
            const int ss_hor = p && f->cur.p.layout != DAV1D_PIXEL_LAYOUT_I444;
2526
32.3k
            const int d = f->frame_hdr->super_res.width_scale_denominator;
2527
32.3k
            const int unit_size_log2 = f->frame_hdr->restoration.unit_size[!!p];
2528
32.3k
            const int rnd = (8 << unit_size_log2) - 1, shift = unit_size_log2 + 3;
2529
32.3k
            const int x = ((4 * ts->tiling.col_start * d >> ss_hor) + rnd) >> shift;
2530
32.3k
            const int px_x = x << (unit_size_log2 + ss_hor);
2531
32.3k
            const int u_idx = unit_idx + ((px_x & 64) >> 6);
2532
32.3k
            const int sb128x = px_x >> 7;
2533
32.3k
            if (sb128x >= f->sr_sb128w) continue;
2534
31.4k
            ts->lr_ref[p] = &f->lf.lr_mask[sb_idx + sb128x].lr[p][u_idx];
2535
54.8k
        } else {
2536
54.8k
            ts->lr_ref[p] = &f->lf.lr_mask[sb_idx].lr[p][unit_idx];
2537
54.8k
        }
2538
2539
86.2k
        ts->lr_ref[p]->filter_v[0] = 3;
2540
86.2k
        ts->lr_ref[p]->filter_v[1] = -7;
2541
86.2k
        ts->lr_ref[p]->filter_v[2] = 15;
2542
86.2k
        ts->lr_ref[p]->filter_h[0] = 3;
2543
86.2k
        ts->lr_ref[p]->filter_h[1] = -7;
2544
86.2k
        ts->lr_ref[p]->filter_h[2] = 15;
2545
86.2k
        ts->lr_ref[p]->sgr_weights[0] = -32;
2546
86.2k
        ts->lr_ref[p]->sgr_weights[1] = 31;
2547
86.2k
    }
2548
2549
143k
    if (f->c->n_tc > 1) {
2550
429k
        for (int p = 0; p < 2; p++)
2551
286k
            atomic_init(&ts->progress[p], row_sb_start);
2552
143k
    }
2553
143k
}
2554
2555
static void read_restoration_info(Dav1dTaskContext *const t,
2556
                                  Av1RestorationUnit *const lr, const int p,
2557
                                  const enum Dav1dRestorationType frame_type)
2558
503k
{
2559
503k
    const Dav1dFrameContext *const f = t->f;
2560
503k
    Dav1dTileState *const ts = t->ts;
2561
503k
    const Av1RestorationUnit *const lr_ref = ts->lr_ref[p];
2562
2563
503k
    if (frame_type == DAV1D_RESTORATION_SWITCHABLE) {
2564
177k
        const int filter = dav1d_msac_decode_symbol_adapt4(&ts->msac,
2565
177k
                               ts->cdf.m.restore_switchable, 2);
2566
177k
        lr->type = filter + !!filter; /* NONE/WIENER/SGRPROJ */
2567
325k
    } else {
2568
325k
        const unsigned type =
2569
325k
            dav1d_msac_decode_bool_adapt(&ts->msac,
2570
325k
                frame_type == DAV1D_RESTORATION_WIENER ?
2571
187k
                ts->cdf.m.restore_wiener : ts->cdf.m.restore_sgrproj);
2572
325k
        lr->type = type ? frame_type : DAV1D_RESTORATION_NONE;
2573
325k
    }
2574
2575
503k
    if (lr->type == DAV1D_RESTORATION_WIENER) {
2576
140k
        lr->filter_v[0] = p ? 0 :
2577
140k
            dav1d_msac_decode_subexp(&ts->msac,
2578
61.6k
                lr_ref->filter_v[0] + 5, 16, 1) - 5;
2579
140k
        lr->filter_v[1] =
2580
140k
            dav1d_msac_decode_subexp(&ts->msac,
2581
140k
                lr_ref->filter_v[1] + 23, 32, 2) - 23;
2582
140k
        lr->filter_v[2] =
2583
140k
            dav1d_msac_decode_subexp(&ts->msac,
2584
140k
                lr_ref->filter_v[2] + 17, 64, 3) - 17;
2585
2586
140k
        lr->filter_h[0] = p ? 0 :
2587
140k
            dav1d_msac_decode_subexp(&ts->msac,
2588
61.6k
                lr_ref->filter_h[0] + 5, 16, 1) - 5;
2589
140k
        lr->filter_h[1] =
2590
140k
            dav1d_msac_decode_subexp(&ts->msac,
2591
140k
                lr_ref->filter_h[1] + 23, 32, 2) - 23;
2592
140k
        lr->filter_h[2] =
2593
140k
            dav1d_msac_decode_subexp(&ts->msac,
2594
140k
                lr_ref->filter_h[2] + 17, 64, 3) - 17;
2595
140k
        memcpy(lr->sgr_weights, lr_ref->sgr_weights, sizeof(lr->sgr_weights));
2596
140k
        ts->lr_ref[p] = lr;
2597
140k
        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
363k
    } else if (lr->type == DAV1D_RESTORATION_SGRPROJ) {
2603
131k
        const unsigned idx = dav1d_msac_decode_bools(&ts->msac, 4);
2604
131k
        const uint16_t *const sgr_params = dav1d_sgr_params[idx];
2605
131k
        lr->type += idx;
2606
131k
        lr->sgr_weights[0] = sgr_params[0] ? dav1d_msac_decode_subexp(&ts->msac,
2607
104k
            lr_ref->sgr_weights[0] + 96, 128, 4) - 96 : 0;
2608
131k
        lr->sgr_weights[1] = sgr_params[1] ? dav1d_msac_decode_subexp(&ts->msac,
2609
95.9k
            lr_ref->sgr_weights[1] + 32, 128, 4) - 32 : 95;
2610
131k
        memcpy(lr->filter_v, lr_ref->filter_v, sizeof(lr->filter_v));
2611
131k
        memcpy(lr->filter_h, lr_ref->filter_h, sizeof(lr->filter_h));
2612
131k
        ts->lr_ref[p] = lr;
2613
131k
        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
131k
    }
2618
503k
}
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
1.02M
int dav1d_decode_tile_sbrow(Dav1dTaskContext *const t) {
2640
1.02M
    const Dav1dFrameContext *const f = t->f;
2641
1.02M
    const enum BlockLevel root_bl = f->seq_hdr->sb128 ? BL_128X128 : BL_64X64;
2642
1.02M
    Dav1dTileState *const ts = t->ts;
2643
1.02M
    const Dav1dContext *const c = f->c;
2644
1.02M
    const int sb_step = f->sb_step;
2645
1.02M
    const int tile_row = ts->tiling.row, tile_col = ts->tiling.col;
2646
1.02M
    const int col_sb_start = f->frame_hdr->tiling.col_start_sb[tile_col];
2647
1.02M
    const int col_sb128_start = col_sb_start >> !f->seq_hdr->sb128;
2648
2649
1.02M
    if (IS_INTER_OR_SWITCH(f->frame_hdr) || f->frame_hdr->allow_intrabc) {
2650
300k
        dav1d_refmvs_tile_sbrow_init(&t->rt, &f->rf, ts->tiling.col_start,
2651
300k
                                     ts->tiling.col_end, ts->tiling.row_start,
2652
300k
                                     ts->tiling.row_end, t->by >> f->sb_shift,
2653
300k
                                     ts->tiling.row, t->frame_thread.pass);
2654
300k
    }
2655
2656
1.02M
    if (IS_INTER_OR_SWITCH(f->frame_hdr) && c->n_fc > 1) {
2657
120k
        const int sby = (t->by - ts->tiling.row_start) >> f->sb_shift;
2658
120k
        int (*const lowest_px)[2] = ts->lowest_pixel[sby];
2659
962k
        for (int n = 0; n < 7; n++)
2660
2.52M
            for (int m = 0; m < 2; m++)
2661
1.68M
                lowest_px[n][m] = INT_MIN;
2662
120k
    }
2663
2664
1.02M
    reset_context(&t->l, IS_KEY_OR_INTRA(f->frame_hdr), t->frame_thread.pass);
2665
1.02M
    if (t->frame_thread.pass == 2) {
2666
472k
        const int off_2pass = c->n_tc > 1 ? f->sb128w * f->frame_hdr->tiling.rows : 0;
2667
472k
        for (t->bx = ts->tiling.col_start,
2668
472k
             t->a = f->a + off_2pass + col_sb128_start + tile_row * f->sb128w;
2669
1.25M
             t->bx < ts->tiling.col_end; t->bx += sb_step)
2670
784k
        {
2671
784k
            if (atomic_load_explicit(c->flush, memory_order_acquire))
2672
75
                return 1;
2673
784k
            if (decode_sb(t, root_bl, dav1d_intra_edge_tree[root_bl]))
2674
0
                return 1;
2675
784k
            if (t->bx & 16 || f->seq_hdr->sb128)
2676
368k
                t->a++;
2677
784k
        }
2678
472k
        f->bd_fn.backup_ipred_edge(t);
2679
472k
        return 0;
2680
472k
    }
2681
2682
549k
    if (f->c->n_tc > 1 && f->frame_hdr->use_ref_frame_mvs) {
2683
8.43k
        f->c->refmvs_dsp.load_tmvs(&f->rf, ts->tiling.row,
2684
8.43k
                                   ts->tiling.col_start >> 1, ts->tiling.col_end >> 1,
2685
8.43k
                                   t->by >> 1, (t->by + sb_step) >> 1);
2686
8.43k
    }
2687
548k
    memset(t->pal_sz_uv[1], 0, sizeof(*t->pal_sz_uv));
2688
548k
    const int sb128y = t->by >> 5;
2689
548k
    for (t->bx = ts->tiling.col_start, t->a = f->a + col_sb128_start + tile_row * f->sb128w,
2690
548k
         t->lf_mask = f->lf.mask + sb128y * f->sb128w + col_sb128_start;
2691
1.65M
         t->bx < ts->tiling.col_end; t->bx += sb_step)
2692
1.10M
    {
2693
1.10M
        if (atomic_load_explicit(c->flush, memory_order_acquire))
2694
299
            return 1;
2695
1.10M
        if (root_bl == BL_128X128) {
2696
312k
            t->cur_sb_cdef_idx_ptr = t->lf_mask->cdef_idx;
2697
312k
            t->cur_sb_cdef_idx_ptr[0] = -1;
2698
312k
            t->cur_sb_cdef_idx_ptr[1] = -1;
2699
312k
            t->cur_sb_cdef_idx_ptr[2] = -1;
2700
312k
            t->cur_sb_cdef_idx_ptr[3] = -1;
2701
795k
        } else {
2702
795k
            t->cur_sb_cdef_idx_ptr =
2703
795k
                &t->lf_mask->cdef_idx[((t->bx & 16) >> 4) +
2704
795k
                                      ((t->by & 16) >> 3)];
2705
795k
            t->cur_sb_cdef_idx_ptr[0] = -1;
2706
795k
        }
2707
        // Restoration filter
2708
4.43M
        for (int p = 0; p < 3; p++) {
2709
3.32M
            if (!((f->lf.restore_planes >> p) & 1U))
2710
2.54M
                continue;
2711
2712
780k
            const int ss_ver = p && f->cur.p.layout == DAV1D_PIXEL_LAYOUT_I420;
2713
780k
            const int ss_hor = p && f->cur.p.layout != DAV1D_PIXEL_LAYOUT_I444;
2714
780k
            const int unit_size_log2 = f->frame_hdr->restoration.unit_size[!!p];
2715
780k
            const int y = t->by * 4 >> ss_ver;
2716
780k
            const int h = (f->cur.p.h + ss_ver) >> ss_ver;
2717
2718
780k
            const int unit_size = 1 << unit_size_log2;
2719
780k
            const unsigned mask = unit_size - 1;
2720
780k
            if (y & mask) continue;
2721
573k
            const int half_unit = unit_size >> 1;
2722
            // Round half up at frame boundaries, if there's more than one
2723
            // restoration unit
2724
573k
            if (y && y + half_unit > h) continue;
2725
2726
558k
            const enum Dav1dRestorationType frame_type = f->frame_hdr->restoration.type[p];
2727
2728
558k
            if (f->frame_hdr->width[0] != f->frame_hdr->width[1]) {
2729
172k
                const int w = (f->sr_cur.p.p.w + ss_hor) >> ss_hor;
2730
172k
                const int n_units = imax(1, (w + half_unit) >> unit_size_log2);
2731
2732
172k
                const int d = f->frame_hdr->super_res.width_scale_denominator;
2733
172k
                const int rnd = unit_size * 8 - 1, shift = unit_size_log2 + 3;
2734
172k
                const int x0 = ((4 *  t->bx            * d >> ss_hor) + rnd) >> shift;
2735
172k
                const int x1 = ((4 * (t->bx + sb_step) * d >> ss_hor) + rnd) >> shift;
2736
2737
362k
                for (int x = x0; x < imin(x1, n_units); x++) {
2738
190k
                    const int px_x = x << (unit_size_log2 + ss_hor);
2739
190k
                    const int sb_idx = (t->by >> 5) * f->sr_sb128w + (px_x >> 7);
2740
190k
                    const int unit_idx = ((t->by & 16) >> 3) + ((px_x & 64) >> 6);
2741
190k
                    Av1RestorationUnit *const lr = &f->lf.lr_mask[sb_idx].lr[p][unit_idx];
2742
2743
190k
                    read_restoration_info(t, lr, p, frame_type);
2744
190k
                }
2745
386k
            } else {
2746
386k
                const int x = 4 * t->bx >> ss_hor;
2747
386k
                if (x & mask) continue;
2748
318k
                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
318k
                if (x && x + half_unit > w) continue;
2752
312k
                const int sb_idx = (t->by >> 5) * f->sr_sb128w + (t->bx >> 5);
2753
312k
                const int unit_idx = ((t->by & 16) >> 3) + ((t->bx & 16) >> 4);
2754
312k
                Av1RestorationUnit *const lr = &f->lf.lr_mask[sb_idx].lr[p][unit_idx];
2755
2756
312k
                read_restoration_info(t, lr, p, frame_type);
2757
312k
            }
2758
558k
        }
2759
1.10M
        if (decode_sb(t, root_bl, dav1d_intra_edge_tree[root_bl]))
2760
1.35k
            return 1;
2761
1.10M
        if (t->bx & 16 || f->seq_hdr->sb128) {
2762
550k
            t->a++;
2763
550k
            t->lf_mask++;
2764
550k
        }
2765
1.10M
    }
2766
2767
547k
    if (f->seq_hdr->ref_frame_mvs && f->c->n_tc > 1 && IS_INTER_OR_SWITCH(f->frame_hdr)) {
2768
19.9k
        dav1d_refmvs_save_tmvs(&f->c->refmvs_dsp, &t->rt,
2769
19.9k
                               ts->tiling.col_start >> 1, ts->tiling.col_end >> 1,
2770
19.9k
                               t->by >> 1, (t->by + sb_step) >> 1);
2771
19.9k
    }
2772
2773
    // backup pre-loopfilter pixels for intra prediction of the next sbrow
2774
547k
    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
547k
    int align_h = (f->bh + 31) & ~31;
2780
547k
    memcpy(&f->lf.tx_lpf_right_edge[0][align_h * tile_col + t->by],
2781
547k
           &t->l.tx_lpf_y[t->by & 16], sb_step);
2782
547k
    const int ss_ver = f->cur.p.layout == DAV1D_PIXEL_LAYOUT_I420;
2783
547k
    align_h >>= ss_ver;
2784
547k
    memcpy(&f->lf.tx_lpf_right_edge[1][align_h * tile_col + (t->by >> ss_ver)],
2785
547k
           &t->l.tx_lpf_uv[(t->by & 16) >> ss_ver], sb_step >> ss_ver);
2786
2787
    // error out on symbol decoder overread
2788
547k
    if (ts->msac.cnt <= -15) return 1;
2789
2790
524k
    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
547k
}
2794
2795
120k
int dav1d_decode_frame_init(Dav1dFrameContext *const f) {
2796
120k
    const Dav1dContext *const c = f->c;
2797
120k
    int retval = DAV1D_ERR(ENOMEM);
2798
2799
120k
    if (f->sbh > f->lf.start_of_tile_row_sz) {
2800
106k
        dav1d_free(f->lf.start_of_tile_row);
2801
106k
        f->lf.start_of_tile_row = dav1d_malloc(ALLOC_TILE, f->sbh * sizeof(uint8_t));
2802
106k
        if (!f->lf.start_of_tile_row) {
2803
0
            f->lf.start_of_tile_row_sz = 0;
2804
0
            goto error;
2805
0
        }
2806
106k
        f->lf.start_of_tile_row_sz = f->sbh;
2807
106k
    }
2808
120k
    int sby = 0;
2809
255k
    for (int tile_row = 0; tile_row < f->frame_hdr->tiling.rows; tile_row++) {
2810
134k
        f->lf.start_of_tile_row[sby++] = tile_row;
2811
1.17M
        while (sby < f->frame_hdr->tiling.row_start_sb[tile_row + 1])
2812
1.04M
            f->lf.start_of_tile_row[sby++] = 0;
2813
134k
    }
2814
2815
120k
    const int n_ts = f->frame_hdr->tiling.cols * f->frame_hdr->tiling.rows;
2816
120k
    if (n_ts != f->n_ts) {
2817
106k
        if (c->n_fc > 1) {
2818
106k
            dav1d_free(f->frame_thread.tile_start_off);
2819
106k
            f->frame_thread.tile_start_off =
2820
106k
                dav1d_malloc(ALLOC_TILE, sizeof(*f->frame_thread.tile_start_off) * n_ts);
2821
106k
            if (!f->frame_thread.tile_start_off) {
2822
0
                f->n_ts = 0;
2823
0
                goto error;
2824
0
            }
2825
106k
        }
2826
106k
        dav1d_free_aligned(f->ts);
2827
106k
        f->ts = dav1d_alloc_aligned(ALLOC_TILE, sizeof(*f->ts) * n_ts, 32);
2828
106k
        if (!f->ts) goto error;
2829
106k
        f->n_ts = n_ts;
2830
106k
    }
2831
2832
120k
    const int a_sz = f->sb128w * f->frame_hdr->tiling.rows * (1 + (c->n_fc > 1 && c->n_tc > 1));
2833
120k
    if (a_sz != f->a_sz) {
2834
106k
        dav1d_free(f->a);
2835
106k
        f->a = dav1d_malloc(ALLOC_TILE, sizeof(*f->a) * a_sz);
2836
106k
        if (!f->a) {
2837
0
            f->a_sz = 0;
2838
0
            goto error;
2839
0
        }
2840
106k
        f->a_sz = a_sz;
2841
106k
    }
2842
2843
120k
    const int num_sb128 = f->sb128w * f->sb128h;
2844
120k
    const uint8_t *const size_mul = ss_size_mul[f->cur.p.layout];
2845
120k
    const int hbd = !!f->seq_hdr->hbd;
2846
120k
    if (c->n_fc > 1) {
2847
120k
        const unsigned sb_step4 = f->sb_step * 4;
2848
120k
        int tile_idx = 0;
2849
255k
        for (int tile_row = 0; tile_row < f->frame_hdr->tiling.rows; tile_row++) {
2850
134k
            const unsigned row_off = f->frame_hdr->tiling.row_start_sb[tile_row] *
2851
134k
                                     sb_step4 * f->sb128w * 128;
2852
134k
            const unsigned b_diff = (f->frame_hdr->tiling.row_start_sb[tile_row + 1] -
2853
134k
                                     f->frame_hdr->tiling.row_start_sb[tile_row]) * sb_step4;
2854
295k
            for (int tile_col = 0; tile_col < f->frame_hdr->tiling.cols; tile_col++) {
2855
160k
                f->frame_thread.tile_start_off[tile_idx++] = row_off + b_diff *
2856
160k
                    f->frame_hdr->tiling.col_start_sb[tile_col] * sb_step4;
2857
160k
            }
2858
134k
        }
2859
2860
120k
        const int lowest_pixel_mem_sz = f->frame_hdr->tiling.cols * f->sbh;
2861
120k
        if (lowest_pixel_mem_sz != f->tile_thread.lowest_pixel_mem_sz) {
2862
106k
            dav1d_free(f->tile_thread.lowest_pixel_mem);
2863
106k
            f->tile_thread.lowest_pixel_mem =
2864
106k
                dav1d_malloc(ALLOC_TILE, lowest_pixel_mem_sz *
2865
106k
                             sizeof(*f->tile_thread.lowest_pixel_mem));
2866
106k
            if (!f->tile_thread.lowest_pixel_mem) {
2867
0
                f->tile_thread.lowest_pixel_mem_sz = 0;
2868
0
                goto error;
2869
0
            }
2870
106k
            f->tile_thread.lowest_pixel_mem_sz = lowest_pixel_mem_sz;
2871
106k
        }
2872
120k
        int (*lowest_pixel_ptr)[7][2] = f->tile_thread.lowest_pixel_mem;
2873
255k
        for (int tile_row = 0, tile_row_base = 0; tile_row < f->frame_hdr->tiling.rows;
2874
134k
             tile_row++, tile_row_base += f->frame_hdr->tiling.cols)
2875
134k
        {
2876
134k
            const int tile_row_sb_h = f->frame_hdr->tiling.row_start_sb[tile_row + 1] -
2877
134k
                                      f->frame_hdr->tiling.row_start_sb[tile_row];
2878
295k
            for (int tile_col = 0; tile_col < f->frame_hdr->tiling.cols; tile_col++) {
2879
160k
                f->ts[tile_row_base + tile_col].lowest_pixel = lowest_pixel_ptr;
2880
160k
                lowest_pixel_ptr += tile_row_sb_h;
2881
160k
            }
2882
134k
        }
2883
2884
120k
        const int cbi_sz = num_sb128 * size_mul[0];
2885
120k
        if (cbi_sz != f->frame_thread.cbi_sz) {
2886
106k
            dav1d_free_aligned(f->frame_thread.cbi);
2887
106k
            f->frame_thread.cbi =
2888
106k
                dav1d_alloc_aligned(ALLOC_BLOCK, sizeof(*f->frame_thread.cbi) *
2889
106k
                                    cbi_sz * 32 * 32 / 4, 64);
2890
106k
            if (!f->frame_thread.cbi) {
2891
0
                f->frame_thread.cbi_sz = 0;
2892
0
                goto error;
2893
0
            }
2894
106k
            f->frame_thread.cbi_sz = cbi_sz;
2895
106k
        }
2896
2897
120k
        const int cf_sz = (num_sb128 * size_mul[0]) << hbd;
2898
120k
        if (cf_sz != f->frame_thread.cf_sz) {
2899
107k
            dav1d_free_aligned(f->frame_thread.cf);
2900
107k
            f->frame_thread.cf =
2901
107k
                dav1d_alloc_aligned(ALLOC_COEF, (size_t)cf_sz * 128 * 128 / 2, 64);
2902
107k
            if (!f->frame_thread.cf) {
2903
0
                f->frame_thread.cf_sz = 0;
2904
0
                goto error;
2905
0
            }
2906
107k
            memset(f->frame_thread.cf, 0, (size_t)cf_sz * 128 * 128 / 2);
2907
107k
            f->frame_thread.cf_sz = cf_sz;
2908
107k
        }
2909
2910
120k
        if (f->frame_hdr->allow_screen_content_tools) {
2911
47.5k
            const int pal_sz = num_sb128 << hbd;
2912
47.5k
            if (pal_sz != f->frame_thread.pal_sz) {
2913
44.0k
                dav1d_free_aligned(f->frame_thread.pal);
2914
44.0k
                f->frame_thread.pal =
2915
44.0k
                    dav1d_alloc_aligned(ALLOC_PAL, sizeof(*f->frame_thread.pal) *
2916
44.0k
                                        pal_sz * 16 * 16, 64);
2917
44.0k
                if (!f->frame_thread.pal) {
2918
0
                    f->frame_thread.pal_sz = 0;
2919
0
                    goto error;
2920
0
                }
2921
44.0k
                f->frame_thread.pal_sz = pal_sz;
2922
44.0k
            }
2923
2924
47.5k
            const int pal_idx_sz = num_sb128 * size_mul[1];
2925
47.5k
            if (pal_idx_sz != f->frame_thread.pal_idx_sz) {
2926
44.0k
                dav1d_free_aligned(f->frame_thread.pal_idx);
2927
44.0k
                f->frame_thread.pal_idx =
2928
44.0k
                    dav1d_alloc_aligned(ALLOC_PAL, sizeof(*f->frame_thread.pal_idx) *
2929
44.0k
                                        pal_idx_sz * 128 * 128 / 8, 64);
2930
44.0k
                if (!f->frame_thread.pal_idx) {
2931
0
                    f->frame_thread.pal_idx_sz = 0;
2932
0
                    goto error;
2933
0
                }
2934
44.0k
                f->frame_thread.pal_idx_sz = pal_idx_sz;
2935
44.0k
            }
2936
73.4k
        } else if (f->frame_thread.pal) {
2937
164
            dav1d_freep_aligned(&f->frame_thread.pal);
2938
164
            dav1d_freep_aligned(&f->frame_thread.pal_idx);
2939
164
            f->frame_thread.pal_sz = f->frame_thread.pal_idx_sz = 0;
2940
164
        }
2941
120k
    }
2942
2943
    // update allocation of block contexts for above
2944
120k
    ptrdiff_t y_stride = f->cur.stride[0], uv_stride = f->cur.stride[1];
2945
120k
    const int has_resize = f->frame_hdr->width[0] != f->frame_hdr->width[1];
2946
120k
    const int need_cdef_lpf_copy = c->n_tc > 1 && has_resize;
2947
120k
    if (y_stride * f->sbh * 4 != f->lf.cdef_buf_plane_sz[0] ||
2948
14.0k
        uv_stride * f->sbh * 8 != f->lf.cdef_buf_plane_sz[1] ||
2949
13.9k
        need_cdef_lpf_copy != f->lf.need_cdef_lpf_copy ||
2950
13.2k
        f->sbh != f->lf.cdef_buf_sbh)
2951
107k
    {
2952
107k
        dav1d_free_aligned(f->lf.cdef_line_buf);
2953
107k
        size_t alloc_sz = 64;
2954
107k
        alloc_sz += (size_t)llabs(y_stride) * 4 * f->sbh << need_cdef_lpf_copy;
2955
107k
        alloc_sz += (size_t)llabs(uv_stride) * 8 * f->sbh << need_cdef_lpf_copy;
2956
107k
        uint8_t *ptr = f->lf.cdef_line_buf = dav1d_alloc_aligned(ALLOC_CDEF, alloc_sz, 32);
2957
107k
        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
107k
        ptr += 32;
2963
107k
        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
107k
        } else {
2967
107k
            f->lf.cdef_line[0][0] = ptr + y_stride * 0;
2968
107k
            f->lf.cdef_line[1][0] = ptr + y_stride * 2;
2969
107k
        }
2970
107k
        ptr += llabs(y_stride) * f->sbh * 4;
2971
107k
        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
107k
        } else {
2977
107k
            f->lf.cdef_line[0][1] = ptr + uv_stride * 0;
2978
107k
            f->lf.cdef_line[0][2] = ptr + uv_stride * 2;
2979
107k
            f->lf.cdef_line[1][1] = ptr + uv_stride * 4;
2980
107k
            f->lf.cdef_line[1][2] = ptr + uv_stride * 6;
2981
107k
        }
2982
2983
107k
        if (need_cdef_lpf_copy) {
2984
20.9k
            ptr += llabs(uv_stride) * f->sbh * 8;
2985
20.9k
            if (y_stride < 0)
2986
0
                f->lf.cdef_lpf_line[0] = ptr - y_stride * (f->sbh * 4 - 1);
2987
20.9k
            else
2988
20.9k
                f->lf.cdef_lpf_line[0] = ptr;
2989
20.9k
            ptr += llabs(y_stride) * f->sbh * 4;
2990
20.9k
            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
20.9k
            } else {
2994
20.9k
                f->lf.cdef_lpf_line[1] = ptr;
2995
20.9k
                f->lf.cdef_lpf_line[2] = ptr + uv_stride * f->sbh * 4;
2996
20.9k
            }
2997
20.9k
        }
2998
2999
107k
        f->lf.cdef_buf_plane_sz[0] = (int) y_stride * f->sbh * 4;
3000
107k
        f->lf.cdef_buf_plane_sz[1] = (int) uv_stride * f->sbh * 8;
3001
107k
        f->lf.need_cdef_lpf_copy = need_cdef_lpf_copy;
3002
107k
        f->lf.cdef_buf_sbh = f->sbh;
3003
107k
    }
3004
3005
120k
    const int sb128 = f->seq_hdr->sb128;
3006
120k
    const int num_lines = c->n_tc > 1 ? f->sbh * 4 << sb128 : 12;
3007
120k
    y_stride = f->sr_cur.p.stride[0], uv_stride = f->sr_cur.p.stride[1];
3008
120k
    if (y_stride * num_lines != f->lf.lr_buf_plane_sz[0] ||
3009
13.9k
        uv_stride * num_lines * 2 != f->lf.lr_buf_plane_sz[1])
3010
107k
    {
3011
107k
        dav1d_free_aligned(f->lf.lr_line_buf);
3012
        // lr simd may overread the input, so slightly over-allocate the lpf buffer
3013
107k
        size_t alloc_sz = 128;
3014
107k
        alloc_sz += (size_t)llabs(y_stride) * num_lines;
3015
107k
        alloc_sz += (size_t)llabs(uv_stride) * num_lines * 2;
3016
107k
        uint8_t *ptr = f->lf.lr_line_buf = dav1d_alloc_aligned(ALLOC_LR, alloc_sz, 64);
3017
107k
        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
107k
        ptr += 64;
3023
107k
        if (y_stride < 0)
3024
0
            f->lf.lr_lpf_line[0] = ptr - y_stride * (num_lines - 1);
3025
107k
        else
3026
107k
            f->lf.lr_lpf_line[0] = ptr;
3027
107k
        ptr += llabs(y_stride) * num_lines;
3028
107k
        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
107k
        } else {
3032
107k
            f->lf.lr_lpf_line[1] = ptr;
3033
107k
            f->lf.lr_lpf_line[2] = ptr + uv_stride * num_lines;
3034
107k
        }
3035
3036
107k
        f->lf.lr_buf_plane_sz[0] = (int) y_stride * num_lines;
3037
107k
        f->lf.lr_buf_plane_sz[1] = (int) uv_stride * num_lines * 2;
3038
107k
    }
3039
3040
    // update allocation for loopfilter masks
3041
120k
    if (num_sb128 != f->lf.mask_sz) {
3042
106k
        dav1d_free(f->lf.mask);
3043
106k
        dav1d_free(f->lf.level);
3044
106k
        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
106k
        f->lf.level = dav1d_malloc(ALLOC_LF, sizeof(*f->lf.level) * num_sb128 * 32 * 32 + 3);
3048
106k
        if (!f->lf.mask || !f->lf.level) {
3049
0
            f->lf.mask_sz = 0;
3050
0
            goto error;
3051
0
        }
3052
106k
        if (c->n_fc > 1) {
3053
106k
            dav1d_free(f->frame_thread.b);
3054
106k
            f->frame_thread.b = dav1d_malloc(ALLOC_BLOCK, sizeof(*f->frame_thread.b) *
3055
106k
                                             num_sb128 * 32 * 32);
3056
106k
            if (!f->frame_thread.b) {
3057
0
                f->lf.mask_sz = 0;
3058
0
                goto error;
3059
0
            }
3060
106k
        }
3061
106k
        f->lf.mask_sz = num_sb128;
3062
106k
    }
3063
3064
120k
    f->sr_sb128w = (f->sr_cur.p.p.w + 127) >> 7;
3065
120k
    const int lr_mask_sz = f->sr_sb128w * f->sb128h;
3066
120k
    if (lr_mask_sz != f->lf.lr_mask_sz) {
3067
106k
        dav1d_free(f->lf.lr_mask);
3068
106k
        f->lf.lr_mask = dav1d_malloc(ALLOC_LR, sizeof(*f->lf.lr_mask) * lr_mask_sz);
3069
106k
        if (!f->lf.lr_mask) {
3070
0
            f->lf.lr_mask_sz = 0;
3071
0
            goto error;
3072
0
        }
3073
106k
        f->lf.lr_mask_sz = lr_mask_sz;
3074
106k
    }
3075
120k
    f->lf.restore_planes =
3076
120k
        ((f->frame_hdr->restoration.type[0] != DAV1D_RESTORATION_NONE) << 0) +
3077
120k
        ((f->frame_hdr->restoration.type[1] != DAV1D_RESTORATION_NONE) << 1) +
3078
120k
        ((f->frame_hdr->restoration.type[2] != DAV1D_RESTORATION_NONE) << 2);
3079
120k
    if (f->frame_hdr->loopfilter.sharpness != f->lf.last_sharpness) {
3080
111k
        dav1d_calc_eih(&f->lf.lim_lut, f->frame_hdr->loopfilter.sharpness);
3081
111k
        f->lf.last_sharpness = f->frame_hdr->loopfilter.sharpness;
3082
111k
    }
3083
120k
    dav1d_calc_lf_values(f->lf.lvl, f->frame_hdr, (int8_t[4]) { 0, 0, 0, 0 });
3084
120k
    memset(f->lf.mask, 0, sizeof(*f->lf.mask) * num_sb128);
3085
3086
120k
    const int ipred_edge_sz = f->sbh * f->sb128w << hbd;
3087
120k
    if (ipred_edge_sz != f->ipred_edge_sz) {
3088
106k
        dav1d_free_aligned(f->ipred_edge[0]);
3089
106k
        uint8_t *ptr = f->ipred_edge[0] =
3090
106k
            dav1d_alloc_aligned(ALLOC_IPRED, ipred_edge_sz * 128 * 3, 64);
3091
106k
        if (!ptr) {
3092
0
            f->ipred_edge_sz = 0;
3093
0
            goto error;
3094
0
        }
3095
106k
        f->ipred_edge[1] = ptr + ipred_edge_sz * 128 * 1;
3096
106k
        f->ipred_edge[2] = ptr + ipred_edge_sz * 128 * 2;
3097
106k
        f->ipred_edge_sz = ipred_edge_sz;
3098
106k
    }
3099
3100
120k
    const int re_sz = f->sb128h * f->frame_hdr->tiling.cols;
3101
120k
    if (re_sz != f->lf.re_sz) {
3102
106k
        dav1d_free(f->lf.tx_lpf_right_edge[0]);
3103
106k
        f->lf.tx_lpf_right_edge[0] = dav1d_malloc(ALLOC_LF, re_sz * 32 * 2);
3104
106k
        if (!f->lf.tx_lpf_right_edge[0]) {
3105
0
            f->lf.re_sz = 0;
3106
0
            goto error;
3107
0
        }
3108
106k
        f->lf.tx_lpf_right_edge[1] = f->lf.tx_lpf_right_edge[0] + re_sz * 32;
3109
106k
        f->lf.re_sz = re_sz;
3110
106k
    }
3111
3112
    // init ref mvs
3113
120k
    if (IS_INTER_OR_SWITCH(f->frame_hdr) || f->frame_hdr->allow_intrabc) {
3114
61.2k
        const int ret =
3115
61.2k
            dav1d_refmvs_init_frame(&f->rf, f->seq_hdr, f->frame_hdr,
3116
61.2k
                                    f->refpoc, f->mvs, f->refrefpoc, f->ref_mvs,
3117
61.2k
                                    f->c->n_tc, f->c->n_fc);
3118
61.2k
        if (ret < 0) goto error;
3119
61.2k
    }
3120
3121
    // setup dequant tables
3122
120k
    init_quant_tables(f->seq_hdr, f->frame_hdr, f->frame_hdr->quant.yac, f->dq);
3123
120k
    if (f->frame_hdr->quant.qm)
3124
1.28M
        for (int i = 0; i < N_RECT_TX_SIZES; i++) {
3125
1.22M
            f->qm[i][0] = dav1d_qm_tbl[f->frame_hdr->quant.qm_y][0][i];
3126
1.22M
            f->qm[i][1] = dav1d_qm_tbl[f->frame_hdr->quant.qm_u][1][i];
3127
1.22M
            f->qm[i][2] = dav1d_qm_tbl[f->frame_hdr->quant.qm_v][1][i];
3128
1.22M
        }
3129
56.5k
    else
3130
56.5k
        memset(f->qm, 0, sizeof(f->qm));
3131
3132
    // setup jnt_comp weights
3133
120k
    if (f->frame_hdr->switchable_comp_refs) {
3134
223k
        for (int i = 0; i < 7; i++) {
3135
195k
            const unsigned ref0poc = f->refp[i].p.frame_hdr->frame_offset;
3136
3137
780k
            for (int j = i + 1; j < 7; j++) {
3138
585k
                const unsigned ref1poc = f->refp[j].p.frame_hdr->frame_offset;
3139
3140
585k
                const unsigned d1 =
3141
585k
                    imin(abs(get_poc_diff(f->seq_hdr->order_hint_n_bits, ref0poc,
3142
585k
                                          f->cur.frame_hdr->frame_offset)), 31);
3143
585k
                const unsigned d0 =
3144
585k
                    imin(abs(get_poc_diff(f->seq_hdr->order_hint_n_bits, ref1poc,
3145
585k
                                          f->cur.frame_hdr->frame_offset)), 31);
3146
585k
                const int order = d0 <= d1;
3147
3148
585k
                static const uint8_t quant_dist_weight[3][2] = {
3149
585k
                    { 2, 3 }, { 2, 5 }, { 2, 7 }
3150
585k
                };
3151
585k
                static const uint8_t quant_dist_lookup_table[4][2] = {
3152
585k
                    { 9, 7 }, { 11, 5 }, { 12, 4 }, { 13, 3 }
3153
585k
                };
3154
3155
585k
                int k;
3156
1.82M
                for (k = 0; k < 3; k++) {
3157
1.41M
                    const int c0 = quant_dist_weight[k][order];
3158
1.41M
                    const int c1 = quant_dist_weight[k][!order];
3159
1.41M
                    const int d0_c0 = d0 * c0;
3160
1.41M
                    const int d1_c1 = d1 * c1;
3161
1.41M
                    if ((d0 > d1 && d0_c0 < d1_c1) || (d0 <= d1 && d0_c0 > d1_c1)) break;
3162
1.41M
                }
3163
3164
585k
                f->jnt_weights[i][j] = quant_dist_lookup_table[k][order];
3165
585k
            }
3166
195k
        }
3167
27.9k
    }
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
120k
    const int has_chroma = f->cur.p.layout != DAV1D_PIXEL_LAYOUT_I400;
3175
120k
    f->lf.p[0] = f->cur.data[0];
3176
120k
    f->lf.p[1] = f->cur.data[has_chroma ? 1 : 0];
3177
120k
    f->lf.p[2] = f->cur.data[has_chroma ? 2 : 0];
3178
120k
    f->lf.sr_p[0] = f->sr_cur.p.data[0];
3179
120k
    f->lf.sr_p[1] = f->sr_cur.p.data[has_chroma ? 1 : 0];
3180
120k
    f->lf.sr_p[2] = f->sr_cur.p.data[has_chroma ? 2 : 0];
3181
3182
120k
    retval = 0;
3183
120k
error:
3184
120k
    return retval;
3185
120k
}
3186
3187
118k
int dav1d_decode_frame_init_cdf(Dav1dFrameContext *const f) {
3188
118k
    const Dav1dContext *const c = f->c;
3189
118k
    int retval = DAV1D_ERR(EINVAL);
3190
3191
118k
    if (f->frame_hdr->refresh_context)
3192
34.0k
        dav1d_cdf_thread_copy(f->out_cdf.data.cdf, &f->in_cdf);
3193
3194
    // parse individual tiles per tile group
3195
118k
    int tile_row = 0, tile_col = 0;
3196
118k
    f->task_thread.update_set = 0;
3197
234k
    for (int i = 0; i < f->n_tile_data; i++) {
3198
118k
        const uint8_t *data = f->tile[i].data.data;
3199
118k
        size_t size = f->tile[i].data.sz;
3200
3201
261k
        for (int j = f->tile[i].start; j <= f->tile[i].end; j++) {
3202
144k
            size_t tile_sz;
3203
144k
            if (j == f->tile[i].end) {
3204
116k
                tile_sz = size;
3205
116k
            } else {
3206
28.4k
                if (f->frame_hdr->tiling.n_bytes > size) goto error;
3207
28.2k
                tile_sz = 0;
3208
60.6k
                for (unsigned k = 0; k < f->frame_hdr->tiling.n_bytes; k++)
3209
32.3k
                    tile_sz |= (unsigned)*data++ << (k * 8);
3210
28.2k
                tile_sz++;
3211
28.2k
                size -= f->frame_hdr->tiling.n_bytes;
3212
28.2k
                if (tile_sz > size) goto error;
3213
28.2k
            }
3214
3215
143k
            setup_tile(&f->ts[j], f, data, tile_sz, tile_row, tile_col++,
3216
143k
                       c->n_fc > 1 ? f->frame_thread.tile_start_off[j] : 0);
3217
3218
143k
            if (tile_col == f->frame_hdr->tiling.cols) {
3219
124k
                tile_col = 0;
3220
124k
                tile_row++;
3221
124k
            }
3222
143k
            if (j == f->frame_hdr->tiling.update && f->frame_hdr->refresh_context)
3223
33.7k
                f->task_thread.update_set = 1;
3224
143k
            data += tile_sz;
3225
143k
            size -= tile_sz;
3226
143k
        }
3227
118k
    }
3228
3229
116k
    if (c->n_tc > 1) {
3230
116k
        const int uses_2pass = c->n_fc > 1;
3231
822k
        for (int n = 0; n < f->sb128w * f->frame_hdr->tiling.rows * (1 + uses_2pass); n++)
3232
705k
            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
116k
    }
3235
3236
116k
    retval = 0;
3237
118k
error:
3238
118k
    return retval;
3239
116k
}
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
538k
void dav1d_decode_frame_exit(Dav1dFrameContext *const f, int retval) {
3288
538k
    const Dav1dContext *const c = f->c;
3289
3290
538k
    if (f->sr_cur.p.data[0])
3291
538k
        atomic_init(&f->task_thread.error, 0);
3292
3293
538k
    if (c->n_fc > 1 && retval && f->frame_thread.cf) {
3294
132k
        memset(f->frame_thread.cf, 0,
3295
132k
               (size_t)f->frame_thread.cf_sz * 128 * 128 / 2);
3296
132k
    }
3297
4.31M
    for (int i = 0; i < 7; i++) {
3298
3.77M
        if (f->refp[i].p.frame_hdr) {
3299
338k
            if (!retval && c->n_fc > 1 && c->strict_std_compliance &&
3300
338k
                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
338k
            dav1d_thread_picture_unref(&f->refp[i]);
3307
338k
        }
3308
3.77M
        dav1d_ref_dec(&f->ref_mvs_ref[i]);
3309
3.77M
    }
3310
3311
538k
    dav1d_picture_unref_internal(&f->cur);
3312
538k
    dav1d_thread_picture_unref(&f->sr_cur);
3313
538k
    dav1d_cdf_thread_unref(&f->in_cdf);
3314
538k
    if (f->frame_hdr && f->frame_hdr->refresh_context) {
3315
64.0k
        if (f->out_cdf.progress)
3316
64.0k
            atomic_store(f->out_cdf.progress, retval == 0 ? 1 : TILE_ERROR);
3317
64.0k
        dav1d_cdf_thread_unref(&f->out_cdf);
3318
64.0k
    }
3319
538k
    dav1d_ref_dec(&f->cur_segmap_ref);
3320
538k
    dav1d_ref_dec(&f->prev_segmap_ref);
3321
538k
    dav1d_ref_dec(&f->mvs_ref);
3322
538k
    dav1d_ref_dec(&f->seq_hdr_ref);
3323
538k
    dav1d_ref_dec(&f->frame_hdr_ref);
3324
3325
663k
    for (int i = 0; i < f->n_tile_data; i++)
3326
124k
        dav1d_data_unref_internal(&f->tile[i].data);
3327
538k
    f->task_thread.retval = retval;
3328
538k
}
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
51.7k
static int get_upscale_x0(const int in_w, const int out_w, const int step) {
3367
51.7k
    const int err = out_w * step - (in_w << 14);
3368
51.7k
    const int x0 = (-((out_w - in_w) << 13) + (out_w >> 1)) / out_w + 128 - (err / 2);
3369
51.7k
    return x0 & 0x3fff;
3370
51.7k
}
3371
3372
125k
int dav1d_submit_frame(Dav1dContext *const c) {
3373
125k
    Dav1dFrameContext *f;
3374
125k
    int res = -1;
3375
3376
    // wait for c->out_delayed[next] and move into c->out if visible
3377
125k
    Dav1dThreadPicture *out_delayed;
3378
125k
    if (c->n_fc > 1) {
3379
125k
        pthread_mutex_lock(&c->task_thread.lock);
3380
125k
        const unsigned next = c->frame_thread.next++;
3381
125k
        if (c->frame_thread.next == c->n_fc)
3382
4.44k
            c->frame_thread.next = 0;
3383
3384
125k
        f = &c->fc[next];
3385
128k
        while (f->n_tile_data > 0)
3386
2.72k
            pthread_cond_wait(&f->task_thread.cond,
3387
2.72k
                              &c->task_thread.lock);
3388
125k
        out_delayed = &c->frame_thread.out_delayed[next];
3389
125k
        if (out_delayed->p.data[0] || atomic_load(&f->task_thread.error)) {
3390
4.42k
            unsigned first = atomic_load(&c->task_thread.first);
3391
4.42k
            if (first + 1U < c->n_fc)
3392
4.42k
                atomic_fetch_add(&c->task_thread.first, 1U);
3393
195
            else
3394
4.42k
                atomic_store(&c->task_thread.first, 0);
3395
4.42k
            atomic_compare_exchange_strong(&c->task_thread.reset_task_cur,
3396
4.42k
                                           &first, UINT_MAX);
3397
4.42k
            if (c->task_thread.cur && c->task_thread.cur < c->n_fc)
3398
1.26k
                c->task_thread.cur--;
3399
4.42k
        }
3400
125k
        const int error = f->task_thread.retval;
3401
125k
        if (error) {
3402
20
            f->task_thread.retval = 0;
3403
20
            c->cached_error = error;
3404
20
            dav1d_data_props_copy(&c->cached_error_props, &out_delayed->p.m);
3405
20
            dav1d_thread_picture_unref(out_delayed);
3406
125k
        } else if (out_delayed->p.data[0]) {
3407
4.40k
            const unsigned progress = atomic_load_explicit(&out_delayed->progress[1],
3408
4.40k
                                                           memory_order_relaxed);
3409
4.40k
            if ((out_delayed->visible || c->output_invisible_frames) &&
3410
4.13k
                progress != FRAME_ERROR)
3411
4.13k
            {
3412
4.13k
                dav1d_thread_picture_ref(&c->out, out_delayed);
3413
4.13k
                c->event_flags |= dav1d_picture_get_event_flags(out_delayed);
3414
4.13k
            }
3415
4.40k
            dav1d_thread_picture_unref(out_delayed);
3416
4.40k
        }
3417
125k
    } else {
3418
0
        f = c->fc;
3419
0
    }
3420
3421
125k
    f->seq_hdr = c->seq_hdr;
3422
125k
    f->seq_hdr_ref = c->seq_hdr_ref;
3423
125k
    dav1d_ref_inc(f->seq_hdr_ref);
3424
125k
    f->frame_hdr = c->frame_hdr;
3425
125k
    f->frame_hdr_ref = c->frame_hdr_ref;
3426
125k
    c->frame_hdr = NULL;
3427
125k
    c->frame_hdr_ref = NULL;
3428
125k
    f->dsp = &c->dsp[f->seq_hdr->hbd];
3429
3430
125k
    const int bpc = 8 + 2 * f->seq_hdr->hbd;
3431
3432
125k
    if (!f->dsp->ipred.intra_pred[DC_PRED]) {
3433
67.2k
        Dav1dDSPContext *const dsp = &c->dsp[f->seq_hdr->hbd];
3434
3435
67.2k
        switch (bpc) {
3436
0
#define assign_bitdepth_case(bd) \
3437
67.2k
            dav1d_cdef_dsp_init_##bd##bpc(&dsp->cdef); \
3438
67.2k
            dav1d_intra_pred_dsp_init_##bd##bpc(&dsp->ipred); \
3439
67.2k
            dav1d_itx_dsp_init_##bd##bpc(&dsp->itx, bpc); \
3440
67.2k
            dav1d_loop_filter_dsp_init_##bd##bpc(&dsp->lf); \
3441
67.2k
            dav1d_loop_restoration_dsp_init_##bd##bpc(&dsp->lr, bpc); \
3442
67.2k
            dav1d_mc_dsp_init_##bd##bpc(&dsp->mc); \
3443
67.2k
            dav1d_film_grain_dsp_init_##bd##bpc(&dsp->fg); \
3444
67.2k
            break
3445
0
#if CONFIG_8BPC
3446
31.6k
        case 8:
3447
31.6k
            assign_bitdepth_case(8);
3448
0
#endif
3449
0
#if CONFIG_16BPC
3450
30.0k
        case 10:
3451
35.6k
        case 12:
3452
35.6k
            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
67.2k
        }
3461
67.2k
    }
3462
3463
125k
#define assign_bitdepth_case(bd) \
3464
125k
        f->bd_fn.recon_b_inter = dav1d_recon_b_inter_##bd##bpc; \
3465
125k
        f->bd_fn.recon_b_intra = dav1d_recon_b_intra_##bd##bpc; \
3466
125k
        f->bd_fn.filter_sbrow = dav1d_filter_sbrow_##bd##bpc; \
3467
125k
        f->bd_fn.filter_sbrow_deblock_cols = dav1d_filter_sbrow_deblock_cols_##bd##bpc; \
3468
125k
        f->bd_fn.filter_sbrow_deblock_rows = dav1d_filter_sbrow_deblock_rows_##bd##bpc; \
3469
125k
        f->bd_fn.filter_sbrow_cdef = dav1d_filter_sbrow_cdef_##bd##bpc; \
3470
125k
        f->bd_fn.filter_sbrow_resize = dav1d_filter_sbrow_resize_##bd##bpc; \
3471
125k
        f->bd_fn.filter_sbrow_lr = dav1d_filter_sbrow_lr_##bd##bpc; \
3472
125k
        f->bd_fn.backup_ipred_edge = dav1d_backup_ipred_edge_##bd##bpc; \
3473
125k
        f->bd_fn.read_coef_blocks = dav1d_read_coef_blocks_##bd##bpc; \
3474
125k
        f->bd_fn.copy_pal_block_y = dav1d_copy_pal_block_y_##bd##bpc; \
3475
125k
        f->bd_fn.copy_pal_block_uv = dav1d_copy_pal_block_uv_##bd##bpc; \
3476
125k
        f->bd_fn.read_pal_plane = dav1d_read_pal_plane_##bd##bpc; \
3477
125k
        f->bd_fn.read_pal_uv = dav1d_read_pal_uv_##bd##bpc
3478
125k
    if (!f->seq_hdr->hbd) {
3479
60.4k
#if CONFIG_8BPC
3480
60.4k
        assign_bitdepth_case(8);
3481
60.4k
#endif
3482
64.8k
    } else {
3483
64.8k
#if CONFIG_16BPC
3484
64.8k
        assign_bitdepth_case(16);
3485
64.8k
#endif
3486
64.8k
    }
3487
125k
#undef assign_bitdepth_case
3488
3489
125k
    int ref_coded_width[7];
3490
125k
    if (IS_INTER_OR_SWITCH(f->frame_hdr)) {
3491
48.7k
        if (f->frame_hdr->primary_ref_frame != DAV1D_PRIMARY_REF_NONE) {
3492
39.9k
            const int pri_ref = f->frame_hdr->refidx[f->frame_hdr->primary_ref_frame];
3493
39.9k
            if (!c->refs[pri_ref].p.p.data[0]) {
3494
28
                res = DAV1D_ERR(EINVAL);
3495
28
                goto error;
3496
28
            }
3497
39.9k
        }
3498
387k
        for (int i = 0; i < 7; i++) {
3499
338k
            const int refidx = f->frame_hdr->refidx[i];
3500
338k
            if (!c->refs[refidx].p.p.data[0] ||
3501
338k
                f->frame_hdr->width[0] * 2 < c->refs[refidx].p.p.p.w ||
3502
338k
                f->frame_hdr->height * 2 < c->refs[refidx].p.p.p.h ||
3503
338k
                f->frame_hdr->width[0] > c->refs[refidx].p.p.p.w * 16 ||
3504
338k
                f->frame_hdr->height > c->refs[refidx].p.p.p.h * 16 ||
3505
338k
                f->seq_hdr->layout != c->refs[refidx].p.p.p.layout ||
3506
338k
                bpc != c->refs[refidx].p.p.p.bpc)
3507
402
            {
3508
682
                for (int j = 0; j < i; j++)
3509
280
                    dav1d_thread_picture_unref(&f->refp[j]);
3510
402
                res = DAV1D_ERR(EINVAL);
3511
402
                goto error;
3512
402
            }
3513
338k
            dav1d_thread_picture_ref(&f->refp[i], &c->refs[refidx].p);
3514
338k
            ref_coded_width[i] = c->refs[refidx].p.p.frame_hdr->width[0];
3515
338k
            if (f->frame_hdr->width[0] != c->refs[refidx].p.p.p.w ||
3516
218k
                f->frame_hdr->height != c->refs[refidx].p.p.p.h)
3517
128k
            {
3518
128k
#define scale_fac(ref_sz, this_sz) \
3519
309k
    ((((ref_sz) << 14) + ((this_sz) >> 1)) / (this_sz))
3520
128k
                f->svc[i][0].scale = scale_fac(c->refs[refidx].p.p.p.w,
3521
128k
                                               f->frame_hdr->width[0]);
3522
128k
                f->svc[i][1].scale = scale_fac(c->refs[refidx].p.p.p.h,
3523
128k
                                               f->frame_hdr->height);
3524
128k
                f->svc[i][0].step = (f->svc[i][0].scale + 8) >> 4;
3525
128k
                f->svc[i][1].step = (f->svc[i][1].scale + 8) >> 4;
3526
209k
            } else {
3527
209k
                f->svc[i][0].scale = f->svc[i][1].scale = 0;
3528
209k
            }
3529
338k
            f->gmv_warp_allowed[i] = f->frame_hdr->gmv[i].type > DAV1D_WM_TYPE_TRANSLATION &&
3530
90.1k
                                     !f->frame_hdr->force_integer_mv &&
3531
79.1k
                                     !dav1d_get_shear_params(&f->frame_hdr->gmv[i]) &&
3532
76.6k
                                     !f->svc[i][0].scale;
3533
338k
        }
3534
48.7k
    }
3535
3536
    // setup entropy
3537
124k
    if (f->frame_hdr->primary_ref_frame == DAV1D_PRIMARY_REF_NONE) {
3538
85.2k
        dav1d_cdf_thread_init_static(&f->in_cdf, f->frame_hdr->quant.yac);
3539
85.2k
    } else {
3540
39.6k
        const int pri_ref = f->frame_hdr->refidx[f->frame_hdr->primary_ref_frame];
3541
39.6k
        dav1d_cdf_thread_ref(&f->in_cdf, &c->cdf[pri_ref]);
3542
39.6k
    }
3543
124k
    if (f->frame_hdr->refresh_context) {
3544
37.5k
        res = dav1d_cdf_thread_alloc(c, &f->out_cdf, c->n_fc > 1);
3545
37.5k
        if (res < 0) goto error;
3546
37.5k
    }
3547
3548
    // FIXME qsort so tiles are in order (for frame threading)
3549
124k
    if (f->n_tile_data_alloc < c->n_tile_data) {
3550
109k
        dav1d_free(f->tile);
3551
109k
        assert(c->n_tile_data < INT_MAX / (int)sizeof(*f->tile));
3552
109k
        f->tile = dav1d_malloc(ALLOC_TILE, c->n_tile_data * sizeof(*f->tile));
3553
109k
        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
109k
        f->n_tile_data_alloc = c->n_tile_data;
3559
109k
    }
3560
124k
    memcpy(f->tile, c->tile, c->n_tile_data * sizeof(*f->tile));
3561
124k
    memset(c->tile, 0, c->n_tile_data * sizeof(*c->tile));
3562
124k
    f->n_tile_data = c->n_tile_data;
3563
124k
    c->n_tile_data = 0;
3564
3565
    // allocate frame
3566
124k
    res = dav1d_thread_picture_alloc(c, f, bpc);
3567
124k
    if (res < 0) goto error;
3568
3569
124k
    if (f->frame_hdr->width[0] != f->frame_hdr->width[1]) {
3570
25.8k
        res = dav1d_picture_alloc_copy(c, &f->cur, f->frame_hdr->width[0], &f->sr_cur.p);
3571
25.8k
        if (res < 0) goto error;
3572
99.0k
    } else {
3573
99.0k
        dav1d_picture_ref(&f->cur, &f->sr_cur.p);
3574
99.0k
    }
3575
3576
124k
    if (f->frame_hdr->width[0] != f->frame_hdr->width[1]) {
3577
25.8k
        f->resize_step[0] = scale_fac(f->cur.p.w, f->sr_cur.p.p.w);
3578
25.8k
        const int ss_hor = f->cur.p.layout != DAV1D_PIXEL_LAYOUT_I444;
3579
25.8k
        const int in_cw = (f->cur.p.w + ss_hor) >> ss_hor;
3580
25.8k
        const int out_cw = (f->sr_cur.p.p.w + ss_hor) >> ss_hor;
3581
25.8k
        f->resize_step[1] = scale_fac(in_cw, out_cw);
3582
25.8k
#undef scale_fac
3583
25.8k
        f->resize_start[0] = get_upscale_x0(f->cur.p.w, f->sr_cur.p.p.w, f->resize_step[0]);
3584
25.8k
        f->resize_start[1] = get_upscale_x0(in_cw, out_cw, f->resize_step[1]);
3585
25.8k
    }
3586
3587
    // move f->cur into output queue
3588
124k
    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
124k
    } else {
3594
124k
        dav1d_thread_picture_ref(out_delayed, &f->sr_cur);
3595
124k
    }
3596
3597
124k
    f->w4 = (f->frame_hdr->width[0] + 3) >> 2;
3598
124k
    f->h4 = (f->frame_hdr->height + 3) >> 2;
3599
124k
    f->bw = ((f->frame_hdr->width[0] + 7) >> 3) << 1;
3600
124k
    f->bh = ((f->frame_hdr->height + 7) >> 3) << 1;
3601
124k
    f->sb128w = (f->bw + 31) >> 5;
3602
124k
    f->sb128h = (f->bh + 31) >> 5;
3603
124k
    f->sb_shift = 4 + f->seq_hdr->sb128;
3604
124k
    f->sb_step = 16 << f->seq_hdr->sb128;
3605
124k
    f->sbh = (f->bh + f->sb_step - 1) >> f->sb_shift;
3606
124k
    f->b4_stride = (f->bw + 31) & ~31;
3607
124k
    f->bitdepth_max = (1 << f->cur.p.bpc) - 1;
3608
124k
    atomic_init(&f->task_thread.error, 0);
3609
124k
    const int uses_2pass = c->n_fc > 1;
3610
124k
    const int cols = f->frame_hdr->tiling.cols;
3611
124k
    const int rows = f->frame_hdr->tiling.rows;
3612
124k
    atomic_store(&f->task_thread.task_counter,
3613
124k
                 (cols * rows + f->sbh) << uses_2pass);
3614
3615
    // ref_mvs
3616
124k
    if (IS_INTER_OR_SWITCH(f->frame_hdr) || f->frame_hdr->allow_intrabc) {
3617
63.8k
        f->mvs_ref = dav1d_ref_create_using_pool(c->refmvs_pool,
3618
63.8k
            sizeof(*f->mvs) * f->sb128h * 16 * (f->b4_stride >> 1));
3619
63.8k
        if (!f->mvs_ref) {
3620
0
            res = DAV1D_ERR(ENOMEM);
3621
0
            goto error;
3622
0
        }
3623
63.8k
        f->mvs = f->mvs_ref->data;
3624
63.8k
        if (!f->frame_hdr->allow_intrabc) {
3625
386k
            for (int i = 0; i < 7; i++)
3626
338k
                f->refpoc[i] = f->refp[i].p.frame_hdr->frame_offset;
3627
48.3k
        } else {
3628
15.4k
            memset(f->refpoc, 0, sizeof(f->refpoc));
3629
15.4k
        }
3630
63.8k
        if (f->frame_hdr->use_ref_frame_mvs) {
3631
65.3k
            for (int i = 0; i < 7; i++) {
3632
57.1k
                const int refidx = f->frame_hdr->refidx[i];
3633
57.1k
                const int ref_w = ((ref_coded_width[i] + 7) >> 3) << 1;
3634
57.1k
                const int ref_h = ((f->refp[i].p.p.h + 7) >> 3) << 1;
3635
57.1k
                if (c->refs[refidx].refmvs != NULL &&
3636
21.2k
                    ref_w == f->bw && ref_h == f->bh)
3637
20.1k
                {
3638
20.1k
                    f->ref_mvs_ref[i] = c->refs[refidx].refmvs;
3639
20.1k
                    dav1d_ref_inc(f->ref_mvs_ref[i]);
3640
20.1k
                    f->ref_mvs[i] = c->refs[refidx].refmvs->data;
3641
37.0k
                } else {
3642
37.0k
                    f->ref_mvs[i] = NULL;
3643
37.0k
                    f->ref_mvs_ref[i] = NULL;
3644
37.0k
                }
3645
57.1k
                memcpy(f->refrefpoc[i], c->refs[refidx].refpoc,
3646
57.1k
                       sizeof(*f->refrefpoc));
3647
57.1k
            }
3648
55.6k
        } else {
3649
55.6k
            memset(f->ref_mvs_ref, 0, sizeof(f->ref_mvs_ref));
3650
55.6k
        }
3651
63.8k
    } else {
3652
61.1k
        f->mvs_ref = NULL;
3653
61.1k
        memset(f->ref_mvs_ref, 0, sizeof(f->ref_mvs_ref));
3654
61.1k
    }
3655
3656
    // segmap
3657
124k
    if (f->frame_hdr->segmentation.enabled) {
3658
        // By default, the previous segmentation map is not initialised.
3659
49.5k
        f->prev_segmap_ref = NULL;
3660
49.5k
        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
49.5k
        if (f->frame_hdr->segmentation.temporal || !f->frame_hdr->segmentation.update_map) {
3665
13.5k
            const int pri_ref = f->frame_hdr->primary_ref_frame;
3666
13.5k
            assert(pri_ref != DAV1D_PRIMARY_REF_NONE);
3667
13.5k
            const int ref_w = ((ref_coded_width[pri_ref] + 7) >> 3) << 1;
3668
13.5k
            const int ref_h = ((f->refp[pri_ref].p.p.h + 7) >> 3) << 1;
3669
13.5k
            if (ref_w == f->bw && ref_h == f->bh) {
3670
10.8k
                f->prev_segmap_ref = c->refs[f->frame_hdr->refidx[pri_ref]].segmap;
3671
10.8k
                if (f->prev_segmap_ref) {
3672
7.26k
                    dav1d_ref_inc(f->prev_segmap_ref);
3673
7.26k
                    f->prev_segmap = f->prev_segmap_ref->data;
3674
7.26k
                }
3675
10.8k
            }
3676
13.5k
        }
3677
3678
49.5k
        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
37.7k
            f->cur_segmap_ref = dav1d_ref_create_using_pool(c->segmap_pool,
3683
37.7k
                sizeof(*f->cur_segmap) * f->b4_stride * 32 * f->sb128h);
3684
37.7k
            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
37.7k
            f->cur_segmap = f->cur_segmap_ref->data;
3690
37.7k
        } else if (f->prev_segmap_ref) {
3691
            // We're not updating an existing map, and we have a valid
3692
            // reference. Use that.
3693
6.64k
            f->cur_segmap_ref = f->prev_segmap_ref;
3694
6.64k
            dav1d_ref_inc(f->cur_segmap_ref);
3695
6.64k
            f->cur_segmap = f->prev_segmap_ref->data;
3696
6.64k
        } else {
3697
            // We need to make a new map. Allocate one here and zero it out.
3698
5.21k
            const size_t segmap_size = sizeof(*f->cur_segmap) * f->b4_stride * 32 * f->sb128h;
3699
5.21k
            f->cur_segmap_ref = dav1d_ref_create_using_pool(c->segmap_pool, segmap_size);
3700
5.21k
            if (!f->cur_segmap_ref) {
3701
0
                res = DAV1D_ERR(ENOMEM);
3702
0
                goto error;
3703
0
            }
3704
5.21k
            f->cur_segmap = f->cur_segmap_ref->data;
3705
5.21k
            memset(f->cur_segmap, 0, segmap_size);
3706
5.21k
        }
3707
75.3k
    } else {
3708
75.3k
        f->cur_segmap = NULL;
3709
75.3k
        f->cur_segmap_ref = NULL;
3710
75.3k
        f->prev_segmap_ref = NULL;
3711
75.3k
    }
3712
3713
    // update references etc.
3714
124k
    const unsigned refresh_frame_flags = f->frame_hdr->refresh_frame_flags;
3715
1.12M
    for (int i = 0; i < 8; i++) {
3716
999k
        if (refresh_frame_flags & (1 << i)) {
3717
767k
            if (c->refs[i].p.p.frame_hdr)
3718
246k
                dav1d_thread_picture_unref(&c->refs[i].p);
3719
767k
            dav1d_thread_picture_ref(&c->refs[i].p, &f->sr_cur);
3720
3721
767k
            dav1d_cdf_thread_unref(&c->cdf[i]);
3722
767k
            if (f->frame_hdr->refresh_context) {
3723
159k
                dav1d_cdf_thread_ref(&c->cdf[i], &f->out_cdf);
3724
607k
            } else {
3725
607k
                dav1d_cdf_thread_ref(&c->cdf[i], &f->in_cdf);
3726
607k
            }
3727
3728
767k
            dav1d_ref_dec(&c->refs[i].segmap);
3729
767k
            c->refs[i].segmap = f->cur_segmap_ref;
3730
767k
            if (f->cur_segmap_ref)
3731
300k
                dav1d_ref_inc(f->cur_segmap_ref);
3732
767k
            dav1d_ref_dec(&c->refs[i].refmvs);
3733
767k
            if (!f->frame_hdr->allow_intrabc) {
3734
648k
                c->refs[i].refmvs = f->mvs_ref;
3735
648k
                if (f->mvs_ref)
3736
180k
                    dav1d_ref_inc(f->mvs_ref);
3737
648k
            }
3738
767k
            memcpy(c->refs[i].refpoc, f->refpoc, sizeof(f->refpoc));
3739
767k
        }
3740
999k
    }
3741
3742
124k
    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
124k
    } else {
3757
124k
        dav1d_task_frame_init(f);
3758
124k
        pthread_mutex_unlock(&c->task_thread.lock);
3759
124k
    }
3760
3761
124k
    return 0;
3762
430
error:
3763
430
    atomic_init(&f->task_thread.error, 1);
3764
430
    dav1d_cdf_thread_unref(&f->in_cdf);
3765
430
    if (f->frame_hdr->refresh_context)
3766
214
        dav1d_cdf_thread_unref(&f->out_cdf);
3767
3.44k
    for (int i = 0; i < 7; i++) {
3768
3.01k
        if (f->refp[i].p.frame_hdr)
3769
0
            dav1d_thread_picture_unref(&f->refp[i]);
3770
3.01k
        dav1d_ref_dec(&f->ref_mvs_ref[i]);
3771
3.01k
    }
3772
430
    if (c->n_fc == 1)
3773
0
        dav1d_thread_picture_unref(&c->out);
3774
430
    else
3775
430
        dav1d_thread_picture_unref(out_delayed);
3776
430
    dav1d_picture_unref_internal(&f->cur);
3777
430
    dav1d_thread_picture_unref(&f->sr_cur);
3778
430
    dav1d_ref_dec(&f->mvs_ref);
3779
430
    dav1d_ref_dec(&f->seq_hdr_ref);
3780
430
    dav1d_ref_dec(&f->frame_hdr_ref);
3781
430
    dav1d_data_props_copy(&c->cached_error_props, &c->in.m);
3782
3783
430
    for (int i = 0; i < f->n_tile_data; i++)
3784
0
        dav1d_data_unref_internal(&f->tile[i].data);
3785
430
    f->n_tile_data = 0;
3786
3787
430
    if (c->n_fc > 1)
3788
430
        pthread_mutex_unlock(&c->task_thread.lock);
3789
3790
430
    return res;
3791
124k
}