Coverage Report

Created: 2026-10-28 06:15

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