Coverage Report

Created: 2026-04-01 07:42

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ffmpeg/libavcodec/vvc/ctu.c
Line
Count
Source
1
/*
2
 * VVC CTU(Coding Tree Unit) parser
3
 *
4
 * Copyright (C) 2022 Nuo Mi
5
 *
6
 * This file is part of FFmpeg.
7
 *
8
 * FFmpeg is free software; you can redistribute it and/or
9
 * modify it under the terms of the GNU Lesser General Public
10
 * License as published by the Free Software Foundation; either
11
 * version 2.1 of the License, or (at your option) any later version.
12
 *
13
 * FFmpeg is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
 * Lesser General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public
19
 * License along with FFmpeg; if not, write to the Free Software
20
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21
 */
22
23
#include "libavutil/error.h"
24
#include "libavutil/refstruct.h"
25
26
#include "cabac.h"
27
#include "ctu.h"
28
#include "inter.h"
29
#include "intra.h"
30
#include "mvs.h"
31
32
#define PROF_TEMP_SIZE (PROF_BLOCK_SIZE) * sizeof(int16_t)
33
34
6.26M
#define TAB_MSM(fc, depth, x, y) fc->tab.msm[(depth)][((y) >> 5) * fc->ps.pps->width32 + ((x) >> 5)]
35
3.88M
#define TAB_ISPMF(fc, x, y) fc->tab.ispmf[((y) >> 6) * fc->ps.pps->width64 + ((x) >> 6)]
36
37
typedef enum VVCModeType {
38
    MODE_TYPE_ALL,
39
    MODE_TYPE_INTER,
40
    MODE_TYPE_INTRA,
41
} VVCModeType;
42
43
static void set_tb_size(const VVCFrameContext *fc, const TransformBlock *tb)
44
10.5M
{
45
10.5M
    const int x_tb      = tb->x0 >> MIN_TU_LOG2;
46
10.5M
    const int y_tb      = tb->y0 >> MIN_TU_LOG2;
47
10.5M
    const int hs        = fc->ps.sps->hshift[tb->c_idx];
48
10.5M
    const int vs        = fc->ps.sps->vshift[tb->c_idx];
49
10.5M
    const int is_chroma = tb->c_idx != 0;
50
10.5M
    const int width     = FFMAX(1, tb->tb_width >> (MIN_TU_LOG2 - hs));
51
10.5M
    const int end       = y_tb + FFMAX(1, tb->tb_height >> (MIN_TU_LOG2 - vs));
52
53
43.1M
    for (int y = y_tb; y < end; y++) {
54
32.6M
        const int off = y * fc->ps.pps->min_tu_width + x_tb;
55
32.6M
        memset(fc->tab.tb_width [is_chroma] + off, tb->tb_width,  width);
56
32.6M
        memset(fc->tab.tb_height[is_chroma] + off, tb->tb_height, width);
57
32.6M
    }
58
10.5M
}
59
60
static void set_tb_tab(uint8_t *tab, uint8_t v, const VVCFrameContext *fc,
61
    const TransformBlock *tb)
62
19.1M
{
63
19.1M
    const int width  = tb->tb_width  << fc->ps.sps->hshift[tb->c_idx];
64
19.1M
    const int height = tb->tb_height << fc->ps.sps->vshift[tb->c_idx];
65
66
83.6M
    for (int h = 0; h < height; h += MIN_TU_SIZE) {
67
64.4M
        const int y = (tb->y0 + h) >> MIN_TU_LOG2;
68
64.4M
        const int off = y * fc->ps.pps->min_tu_width + (tb->x0 >> MIN_TU_LOG2);
69
64.4M
        const int w = FFMAX(1, width >> MIN_TU_LOG2);
70
64.4M
        memset(tab + off, v, w);
71
64.4M
    }
72
19.1M
}
73
74
// 8.7.1 Derivation process for quantization parameters
75
static int get_qp_y_pred(const VVCLocalContext *lc)
76
768k
{
77
768k
    const VVCFrameContext *fc     = lc->fc;
78
768k
    const VVCSPS *sps       = fc->ps.sps;
79
768k
    const VVCPPS *pps       = fc->ps.pps;
80
768k
    const CodingUnit *cu    = lc->cu;
81
768k
    const int ctb_log2_size = sps->ctb_log2_size_y;
82
768k
    const int ctb_size_mask = (1 << ctb_log2_size) - 1;
83
768k
    const int xQg           = lc->parse.cu_qg_top_left_x;
84
768k
    const int yQg           = lc->parse.cu_qg_top_left_y;
85
768k
    const int min_cb_width  = fc->ps.pps->min_cb_width;
86
768k
    const int x_cb          = cu->x0 >> sps->min_cb_log2_size_y;
87
768k
    const int y_cb          = cu->y0 >> sps->min_cb_log2_size_y;
88
768k
    const int rx            = cu->x0 >> ctb_log2_size;
89
768k
    const int ry            = cu->y0 >> ctb_log2_size;
90
768k
    const int in_same_ctb_a = ((xQg - 1) >> ctb_log2_size) == rx && (yQg >> ctb_log2_size) == ry;
91
768k
    const int in_same_ctb_b = (xQg >> ctb_log2_size) == rx && ((yQg - 1) >> ctb_log2_size) == ry;
92
768k
    int qPy_pred, qPy_a, qPy_b;
93
94
768k
    if (lc->na.cand_up) {
95
1.25k
        const int first_qg_in_ctu = !(xQg & ctb_size_mask) &&  !(yQg & ctb_size_mask);
96
1.25k
        const int qPy_up          = fc->tab.qp[LUMA][x_cb + (y_cb - 1) * min_cb_width];
97
1.25k
        if (first_qg_in_ctu && pps->ctb_to_col_bd[xQg >> ctb_log2_size] == xQg >> ctb_log2_size)
98
16
            return qPy_up;
99
1.25k
    }
100
101
    // qPy_pred
102
768k
    qPy_pred = lc->ep->is_first_qg ? lc->sc->sh.slice_qp_y : lc->ep->qp_y;
103
104
    // qPy_b
105
768k
    if (!lc->na.cand_up || !in_same_ctb_b)
106
767k
        qPy_b = qPy_pred;
107
1.01k
    else
108
1.01k
        qPy_b = fc->tab.qp[LUMA][x_cb + (y_cb - 1) * min_cb_width];
109
110
    // qPy_a
111
768k
    if (!lc->na.cand_left || !in_same_ctb_a)
112
767k
        qPy_a = qPy_pred;
113
1.00k
    else
114
1.00k
        qPy_a = fc->tab.qp[LUMA][(x_cb - 1) + y_cb * min_cb_width];
115
116
768k
    av_assert2(qPy_a >= -fc->ps.sps->qp_bd_offset && qPy_a <= 63);
117
768k
    av_assert2(qPy_b >= -fc->ps.sps->qp_bd_offset && qPy_b <= 63);
118
119
768k
    return (qPy_a + qPy_b + 1) >> 1;
120
768k
}
121
122
static void set_cb_tab(const VVCLocalContext *lc, uint8_t *tab, const uint8_t v)
123
58.4M
{
124
58.4M
    const VVCFrameContext *fc   = lc->fc;
125
58.4M
    const VVCPPS *pps           = fc->ps.pps;
126
58.4M
    const CodingUnit *cu        = lc->cu;
127
58.4M
    const int log2_min_cb_size  = fc->ps.sps->min_cb_log2_size_y;
128
58.4M
    const int x_cb              = cu->x0 >> log2_min_cb_size;
129
58.4M
    const int y_cb              = cu->y0 >> log2_min_cb_size;
130
58.4M
    const int cb_width          = cu->cb_width;
131
58.4M
    const int cb_height         = cu->cb_height;
132
58.4M
    int x                       = y_cb * pps->min_cb_width + x_cb;
133
134
236M
    for (int y = 0; y < (cb_height >> log2_min_cb_size); y++) {
135
177M
        const int width = cb_width >> log2_min_cb_size;
136
137
177M
        memset(&tab[x], v, width);
138
177M
        x += pps->min_cb_width;
139
177M
    }
140
58.4M
}
141
142
static int set_qp_y(VVCLocalContext *lc, const int x0, const int y0, const int has_qp_delta)
143
6.61M
{
144
6.61M
    const VVCSPS *sps   = lc->fc->ps.sps;
145
6.61M
    EntryPoint *ep      = lc->ep;
146
6.61M
    CodingUnit *cu      = lc->cu;
147
6.61M
    int cu_qp_delta     = 0;
148
149
6.61M
    if (!lc->fc->ps.pps->r->pps_cu_qp_delta_enabled_flag) {
150
4.62M
        ep->qp_y = lc->sc->sh.slice_qp_y;
151
4.62M
    } else if (ep->is_first_qg || (lc->parse.cu_qg_top_left_x == x0 && lc->parse.cu_qg_top_left_y == y0)) {
152
768k
        ep->qp_y = get_qp_y_pred(lc);
153
768k
        ep->is_first_qg = 0;
154
768k
    }
155
156
6.61M
    if (has_qp_delta) {
157
737k
        const int cu_qp_delta_abs = ff_vvc_cu_qp_delta_abs(lc);
158
159
737k
        if (cu_qp_delta_abs)
160
557k
            cu_qp_delta = ff_vvc_cu_qp_delta_sign_flag(lc) ? -cu_qp_delta_abs : cu_qp_delta_abs;
161
737k
        if (cu_qp_delta > (31 + sps->qp_bd_offset / 2) || cu_qp_delta < -(32 + sps->qp_bd_offset / 2))
162
2.26k
            return AVERROR_INVALIDDATA;
163
735k
        lc->parse.is_cu_qp_delta_coded = 1;
164
165
735k
        if (cu_qp_delta) {
166
555k
            int off = sps->qp_bd_offset;
167
555k
            ep->qp_y = FFUMOD(ep->qp_y + cu_qp_delta + 64 + 2 * off, 64 + off) - off;
168
555k
        }
169
735k
    }
170
171
6.61M
    set_cb_tab(lc, lc->fc->tab.qp[LUMA], ep->qp_y);
172
6.61M
    cu->qp[LUMA] = ep->qp_y;
173
174
6.61M
    return 0;
175
6.61M
}
176
177
static void set_qp_c_tab(const VVCLocalContext *lc, const TransformUnit *tu, const TransformBlock *tb)
178
7.82M
{
179
7.82M
    const int is_jcbcr = tu->joint_cbcr_residual_flag && tu->coded_flag[CB] && tu->coded_flag[CR];
180
7.82M
    const int idx = is_jcbcr ? JCBCR : tb->c_idx;
181
182
7.82M
    set_tb_tab(lc->fc->tab.qp[tb->c_idx], lc->cu->qp[idx], lc->fc, tb);
183
7.82M
}
184
185
static void set_qp_c(VVCLocalContext *lc)
186
9.30M
{
187
9.30M
    const VVCFrameContext *fc       = lc->fc;
188
9.30M
    const VVCSPS *sps               = fc->ps.sps;
189
9.30M
    const VVCPPS *pps               = fc->ps.pps;
190
9.30M
    const H266RawSliceHeader *rsh   = lc->sc->sh.r;
191
9.30M
    CodingUnit *cu                  = lc->cu;
192
9.30M
    const int x_center              = cu->x0 + cu->cb_width  / 2;
193
9.30M
    const int y_center              = cu->y0 + cu->cb_height / 2;
194
9.30M
    const int single_tree           = cu->tree_type == SINGLE_TREE;
195
9.30M
    const int qp_luma               = (single_tree ? lc->ep->qp_y : ff_vvc_get_qPy(fc, x_center, y_center)) + sps->qp_bd_offset;
196
9.30M
    const int qp_chroma             = av_clip(qp_luma, 0, MAX_QP + sps->qp_bd_offset);
197
9.30M
    const int sh_chroma_qp_offset[] = {
198
9.30M
        rsh->sh_cb_qp_offset,
199
9.30M
        rsh->sh_cr_qp_offset,
200
9.30M
        rsh->sh_joint_cbcr_qp_offset,
201
9.30M
    };
202
9.30M
    int qp;
203
204
37.0M
    for (int i = CB - 1; i < CR + sps->r->sps_joint_cbcr_enabled_flag; i++) {
205
27.7M
        qp = sps->chroma_qp_table[i][qp_chroma];
206
27.7M
        qp = qp + pps->chroma_qp_offset[i] + sh_chroma_qp_offset[i] + lc->parse.chroma_qp_offset[i];
207
27.7M
        qp = av_clip(qp, -sps->qp_bd_offset, MAX_QP) + sps->qp_bd_offset;
208
27.7M
        cu->qp[i + 1] = qp;
209
27.7M
    }
210
9.30M
}
211
212
static TransformUnit* alloc_tu(VVCFrameContext *fc, CodingUnit *cu)
213
9.62M
{
214
9.62M
    TransformUnit *tu = av_refstruct_pool_get(fc->tu_pool);
215
9.62M
    if (!tu)
216
0
        return NULL;
217
218
9.62M
    tu->next = NULL;
219
220
9.62M
    if (cu->tus.tail)
221
211k
        cu->tus.tail->next =  tu;
222
9.40M
    else
223
9.40M
        cu->tus.head = tu;
224
9.62M
    cu->tus.tail = tu;
225
226
9.62M
    return tu;
227
9.62M
}
228
229
static TransformUnit* add_tu(VVCFrameContext *fc, CodingUnit *cu, const int x0, const int y0, const int tu_width, const int tu_height)
230
9.62M
{
231
9.62M
    TransformUnit *tu = alloc_tu(fc, cu);
232
233
9.62M
    if (!tu)
234
0
        return NULL;
235
236
9.62M
    tu->x0 = x0;
237
9.62M
    tu->y0 = y0;
238
9.62M
    tu->width = tu_width;
239
9.62M
    tu->height = tu_height;
240
9.62M
    tu->joint_cbcr_residual_flag = 0;
241
9.62M
    memset(tu->coded_flag, 0, sizeof(tu->coded_flag));
242
9.62M
    tu->avail[LUMA] = tu->avail[CHROMA] = 0;
243
9.62M
    tu->nb_tbs = 0;
244
245
9.62M
    return tu;
246
9.62M
}
247
248
static TransformBlock* add_tb(TransformUnit *tu, VVCLocalContext *lc,
249
    const int x0, const int y0, const int tb_width, const int tb_height, const int c_idx)
250
14.4M
{
251
14.4M
    TransformBlock *tb;
252
253
14.4M
    tb = &tu->tbs[tu->nb_tbs++];
254
14.4M
    tb->has_coeffs = 0;
255
14.4M
    tb->x0 = x0;
256
14.4M
    tb->y0 = y0;
257
14.4M
    tb->tb_width  = tb_width;
258
14.4M
    tb->tb_height = tb_height;
259
14.4M
    tb->log2_tb_width  = av_log2(tb_width);
260
14.4M
    tb->log2_tb_height = av_log2(tb_height);
261
262
14.4M
    tb->max_scan_x = tb->max_scan_y = 0;
263
14.4M
    tb->min_scan_x = tb->min_scan_y = 0;
264
265
14.4M
    tb->c_idx = c_idx;
266
14.4M
    tb->ts = 0;
267
14.4M
    tb->coeffs = lc->coeffs;
268
14.4M
    lc->coeffs += tb_width * tb_height;
269
14.4M
    tu->avail[!!c_idx] = true;
270
14.4M
    return tb;
271
14.4M
}
272
273
static uint8_t tu_y_coded_flag_decode(VVCLocalContext *lc, const int is_sbt_not_coded,
274
    const int sub_tu_index, const int is_isp, const int is_chroma_coded)
275
6.44M
{
276
6.44M
    uint8_t tu_y_coded_flag = 0;
277
6.44M
    const VVCSPS *sps       = lc->fc->ps.sps;
278
6.44M
    CodingUnit *cu          = lc->cu;
279
280
6.44M
    if (!is_sbt_not_coded) {
281
6.43M
        int has_y_coded_flag = sub_tu_index < cu->num_intra_subpartitions - 1 || !lc->parse.infer_tu_cbf_luma;
282
6.43M
        if (!is_isp) {
283
6.14M
            const int is_large = cu->cb_width > sps->max_tb_size_y || cu->cb_height > sps->max_tb_size_y;
284
6.14M
            has_y_coded_flag = (cu->pred_mode == MODE_INTRA && !cu->act_enabled_flag) || is_chroma_coded || is_large;
285
6.14M
        }
286
6.43M
        tu_y_coded_flag = has_y_coded_flag ? ff_vvc_tu_y_coded_flag(lc) : 1;
287
6.43M
    }
288
6.44M
    if (is_isp)
289
290k
        lc->parse.infer_tu_cbf_luma = lc->parse.infer_tu_cbf_luma && !tu_y_coded_flag;
290
6.44M
    return tu_y_coded_flag;
291
6.44M
}
292
293
static void chroma_qp_offset_decode(VVCLocalContext *lc, const int is_128, const int is_chroma_coded)
294
3.89M
{
295
3.89M
    const VVCPPS *pps               = lc->fc->ps.pps;
296
3.89M
    const H266RawSliceHeader *rsh   = lc->sc->sh.r;
297
298
3.89M
    if ((is_128 || is_chroma_coded) &&
299
1.28M
        rsh->sh_cu_chroma_qp_offset_enabled_flag && !lc->parse.is_cu_chroma_qp_offset_coded) {
300
19.3k
        const int cu_chroma_qp_offset_flag = ff_vvc_cu_chroma_qp_offset_flag(lc);
301
19.3k
        if (cu_chroma_qp_offset_flag) {
302
7.85k
            int cu_chroma_qp_offset_idx = 0;
303
7.85k
            if (pps->r->pps_chroma_qp_offset_list_len_minus1 > 0)
304
4.14k
                cu_chroma_qp_offset_idx = ff_vvc_cu_chroma_qp_offset_idx(lc);
305
31.4k
            for (int i = CB - 1; i < JCBCR; i++)
306
23.5k
                lc->parse.chroma_qp_offset[i] = pps->chroma_qp_offset_list[cu_chroma_qp_offset_idx][i];
307
11.5k
        } else {
308
11.5k
            memset(lc->parse.chroma_qp_offset, 0, sizeof(lc->parse.chroma_qp_offset));
309
11.5k
        }
310
19.3k
        lc->parse.is_cu_chroma_qp_offset_coded = 1;
311
19.3k
    }
312
3.89M
}
313
314
static int hls_transform_unit(VVCLocalContext *lc, int x0, int y0,int tu_width, int tu_height, int sub_tu_index, int ch_type)
315
9.39M
{
316
9.39M
    VVCFrameContext *fc = lc->fc;
317
9.39M
    const VVCSPS *sps   = fc->ps.sps;
318
9.39M
    const VVCPPS *pps   = fc->ps.pps;
319
9.39M
    CodingUnit *cu      = lc->cu;
320
9.39M
    TransformUnit *tu   = add_tu(fc, cu, x0, y0, tu_width, tu_height);
321
9.39M
    const int min_cb_width      = pps->min_cb_width;
322
9.39M
    const VVCTreeType tree_type = cu->tree_type;
323
9.39M
    const int is_128            = cu->cb_width > 64 || cu->cb_height > 64;
324
9.39M
    const int is_isp            = cu->isp_split_type != ISP_NO_SPLIT;
325
9.39M
    const int is_isp_last_tu    = is_isp && (sub_tu_index == cu->num_intra_subpartitions - 1);
326
9.39M
    const int is_sbt_not_coded  = cu->sbt_flag &&
327
12.9k
        ((sub_tu_index == 0 && cu->sbt_pos_flag) || (sub_tu_index == 1 && !cu->sbt_pos_flag));
328
9.39M
    const int chroma_available  = tree_type != DUAL_TREE_LUMA && sps->r->sps_chroma_format_idc &&
329
3.87M
        (!is_isp || is_isp_last_tu);
330
9.39M
    int ret, xc, yc, wc, hc, is_chroma_coded;
331
332
9.39M
    if (!tu)
333
0
        return AVERROR_INVALIDDATA;
334
335
9.39M
    if (tree_type == SINGLE_TREE && is_isp_last_tu) {
336
32.4k
        const int x_cu = x0 >> fc->ps.sps->min_cb_log2_size_y;
337
32.4k
        const int y_cu = y0 >> fc->ps.sps->min_cb_log2_size_y;
338
32.4k
        xc = SAMPLE_CTB(fc->tab.cb_pos_x[ch_type],  x_cu, y_cu);
339
32.4k
        yc = SAMPLE_CTB(fc->tab.cb_pos_y[ch_type],  x_cu, y_cu);
340
32.4k
        wc = SAMPLE_CTB(fc->tab.cb_width[ch_type],  x_cu, y_cu);
341
32.4k
        hc = SAMPLE_CTB(fc->tab.cb_height[ch_type], x_cu, y_cu);
342
9.36M
    } else {
343
9.36M
        xc = x0, yc = y0, wc = tu_width, hc = tu_height;
344
9.36M
    }
345
346
9.39M
    if (chroma_available && !is_sbt_not_coded) {
347
3.79M
        tu->coded_flag[CB] = ff_vvc_tu_cb_coded_flag(lc);
348
3.79M
        tu->coded_flag[CR] = ff_vvc_tu_cr_coded_flag(lc, tu->coded_flag[CB]);
349
3.79M
    }
350
351
9.39M
    is_chroma_coded = chroma_available && (tu->coded_flag[CB] || tu->coded_flag[CR]);
352
353
9.39M
    if (tree_type != DUAL_TREE_CHROMA) {
354
6.44M
        int has_qp_delta;
355
6.44M
        tu->coded_flag[LUMA] = tu_y_coded_flag_decode(lc, is_sbt_not_coded, sub_tu_index, is_isp, is_chroma_coded);
356
6.44M
        has_qp_delta = (is_128 || tu->coded_flag[LUMA] || is_chroma_coded) &&
357
5.87M
            pps->r->pps_cu_qp_delta_enabled_flag && !lc->parse.is_cu_qp_delta_coded;
358
6.44M
        ret = set_qp_y(lc, x0, y0, has_qp_delta);
359
6.44M
        if (ret < 0)
360
2.25k
            return ret;
361
6.44M
        add_tb(tu, lc, x0, y0, tu_width, tu_height, LUMA);
362
6.44M
    }
363
9.39M
    if (tree_type != DUAL_TREE_LUMA) {
364
3.89M
        chroma_qp_offset_decode(lc, is_128, is_chroma_coded);
365
3.89M
        if (chroma_available) {
366
3.80M
            const int hs = sps->hshift[CHROMA];
367
3.80M
            const int vs = sps->vshift[CHROMA];
368
3.80M
            add_tb(tu, lc, xc, yc, wc >> hs, hc >> vs, CB);
369
3.80M
            add_tb(tu, lc, xc, yc, wc >> hs, hc >> vs, CR);
370
3.80M
        }
371
3.89M
    }
372
9.39M
    if (sps->r->sps_joint_cbcr_enabled_flag && ((cu->pred_mode == MODE_INTRA &&
373
8.98M
        (tu->coded_flag[CB] || tu->coded_flag[CR])) ||
374
8.05M
        (tu->coded_flag[CB] && tu->coded_flag[CR])) &&
375
1.22M
        chroma_available) {
376
1.22M
        tu->joint_cbcr_residual_flag = ff_vvc_tu_joint_cbcr_residual_flag(lc, tu->coded_flag[1], tu->coded_flag[2]);
377
1.22M
    }
378
379
23.4M
    for (int i = 0; i < tu->nb_tbs; i++) {
380
14.0M
        TransformBlock *tb  = &tu->tbs[i];
381
14.0M
        const int is_chroma = tb->c_idx != LUMA;
382
14.0M
        tb->has_coeffs = tu->coded_flag[tb->c_idx];
383
14.0M
        if (tb->has_coeffs && is_chroma)
384
1.89M
            tb->has_coeffs = tb->c_idx == CB ? 1 : !(tu->coded_flag[CB] && tu->joint_cbcr_residual_flag);
385
14.0M
        if (tb->has_coeffs) {
386
7.49M
            tb->ts = cu->bdpcm_flag[tb->c_idx];
387
7.49M
            if (sps->r->sps_transform_skip_enabled_flag && !cu->bdpcm_flag[tb->c_idx] &&
388
5.84M
                tb->tb_width <= sps->max_ts_size && tb->tb_height <= sps->max_ts_size &&
389
5.36M
                !cu->sbt_flag && (is_chroma || !is_isp)) {
390
5.26M
                tb->ts = ff_vvc_transform_skip_flag(lc, is_chroma);
391
5.26M
            }
392
7.49M
            ret = ff_vvc_residual_coding(lc, tb);
393
7.49M
            if (ret < 0)
394
0
                return ret;
395
7.49M
            set_tb_tab(fc->tab.tu_coded_flag[tb->c_idx], tu->coded_flag[tb->c_idx], fc, tb);
396
7.49M
        } else if (cu->act_enabled_flag) {
397
343k
            memset(tb->coeffs, 0, tb->tb_width * tb->tb_height * sizeof(*tb->coeffs));
398
343k
        }
399
14.0M
        if (tb->c_idx != CR)
400
10.2M
            set_tb_size(fc, tb);
401
14.0M
        if (tb->c_idx == CB)
402
3.80M
            set_tb_tab(fc->tab.tu_joint_cbcr_residual_flag, tu->joint_cbcr_residual_flag, fc, tb);
403
14.0M
    }
404
405
9.39M
    return 0;
406
9.39M
}
407
408
static int hls_transform_tree(VVCLocalContext *lc, int x0, int y0,int tu_width, int tu_height, int ch_type)
409
9.18M
{
410
9.18M
    const CodingUnit *cu = lc->cu;
411
9.18M
    const VVCSPS *sps = lc->fc->ps.sps;
412
9.18M
    int ret;
413
414
9.18M
    lc->parse.infer_tu_cbf_luma = 1;
415
9.18M
    if (cu->isp_split_type == ISP_NO_SPLIT && !cu->sbt_flag) {
416
9.08M
        if (tu_width > sps->max_tb_size_y || tu_height > sps->max_tb_size_y) {
417
96
            const int ver_split_first = tu_width > sps->max_tb_size_y && tu_width > tu_height;
418
96
            const int trafo_width  =  ver_split_first ? (tu_width  / 2) : tu_width;
419
96
            const int trafo_height = !ver_split_first ? (tu_height / 2) : tu_height;
420
421
192
            #define TRANSFORM_TREE(x, y) do {                                           \
422
192
                ret = hls_transform_tree(lc, x, y, trafo_width, trafo_height, ch_type);  \
423
192
                if (ret < 0)                                                            \
424
192
                    return ret;                                                         \
425
192
            } while (0)
426
427
96
            TRANSFORM_TREE(x0, y0);
428
96
            if (ver_split_first)
429
65
                TRANSFORM_TREE(x0 + trafo_width, y0);
430
31
            else
431
31
                TRANSFORM_TREE(x0, y0 + trafo_height);
432
433
9.08M
        } else {
434
9.08M
            ret = hls_transform_unit(lc, x0, y0, tu_width, tu_height, 0, ch_type);
435
9.08M
            if (ret < 0)
436
1.96k
                return ret;
437
438
9.08M
        }
439
9.08M
    } else if (cu->sbt_flag) {
440
6.53k
        if (!cu->sbt_horizontal_flag) {
441
4.79k
            #define TRANSFORM_UNIT(x, width, idx) do {                              \
442
4.79k
                ret = hls_transform_unit(lc, x, y0, width, tu_height, idx, ch_type); \
443
4.79k
                if (ret < 0)                                                        \
444
4.79k
                    return ret;                                                     \
445
4.79k
            } while (0)
446
447
2.40k
            const int trafo_width = tu_width * lc->parse.sbt_num_fourths_tb0 / 4;
448
2.40k
            TRANSFORM_UNIT(x0, trafo_width, 0);
449
2.39k
            TRANSFORM_UNIT(x0 + trafo_width, tu_width - trafo_width, 1);
450
451
2.39k
            #undef TRANSFORM_UNIT
452
4.13k
        } else {
453
8.10k
            #define TRANSFORM_UNIT(y, height, idx) do {                             \
454
8.10k
                ret = hls_transform_unit(lc, x0, y, tu_width, height, idx, ch_type); \
455
8.10k
                if (ret < 0)                                                        \
456
8.10k
                    return ret;                                                     \
457
8.10k
            } while (0)
458
459
4.13k
            const int trafo_height = tu_height * lc->parse.sbt_num_fourths_tb0 / 4;
460
4.13k
            TRANSFORM_UNIT(y0, trafo_height, 0);
461
3.97k
            TRANSFORM_UNIT(y0 + trafo_height, tu_height - trafo_height, 1);
462
463
3.97k
            #undef TRANSFORM_UNIT
464
3.97k
        }
465
85.8k
    } else if (cu->isp_split_type == ISP_HOR_SPLIT) {
466
37.7k
        const int trafo_height = tu_height / cu->num_intra_subpartitions;
467
161k
        for (int i = 0; i < cu->num_intra_subpartitions; i++) {
468
124k
            ret = hls_transform_unit(lc, x0, y0 + trafo_height * i, tu_width, trafo_height, i, 0);
469
124k
            if (ret < 0)
470
75
                return ret;
471
124k
        }
472
48.0k
    } else if (cu->isp_split_type == ISP_VER_SPLIT) {
473
48.0k
        const int trafo_width = tu_width / cu->num_intra_subpartitions;
474
214k
        for (int i = 0; i < cu->num_intra_subpartitions; i++) {
475
166k
            ret = hls_transform_unit(lc, x0 + trafo_width * i , y0, trafo_width, tu_height, i, 0);
476
166k
            if (ret < 0)
477
37
                return ret;
478
166k
        }
479
48.0k
    }
480
481
9.17M
    return 0;
482
9.18M
}
483
484
static int skipped_transform_tree(VVCLocalContext *lc, int x0, int y0,int tu_width, int tu_height)
485
149k
{
486
149k
    VVCFrameContext *fc  = lc->fc;
487
149k
    const CodingUnit *cu = lc->cu;
488
149k
    const VVCSPS *sps    = fc->ps.sps;
489
490
149k
    if (tu_width > sps->max_tb_size_y || tu_height > sps->max_tb_size_y) {
491
0
        const int ver_split_first = tu_width > sps->max_tb_size_y && tu_width > tu_height;
492
0
        const int trafo_width  =  ver_split_first ? (tu_width  / 2) : tu_width;
493
0
        const int trafo_height = !ver_split_first ? (tu_height / 2) : tu_height;
494
495
0
        #define SKIPPED_TRANSFORM_TREE(x, y) do {                                   \
496
0
            int ret = skipped_transform_tree(lc, x, y, trafo_width, trafo_height);  \
497
0
            if (ret < 0)                                                            \
498
0
                return ret;                                                         \
499
0
        } while (0)
500
501
0
        SKIPPED_TRANSFORM_TREE(x0, y0);
502
0
        if (ver_split_first)
503
0
            SKIPPED_TRANSFORM_TREE(x0 + trafo_width, y0);
504
0
        else
505
0
            SKIPPED_TRANSFORM_TREE(x0, y0 + trafo_height);
506
149k
    } else {
507
149k
        TransformUnit *tu    = add_tu(fc, lc->cu, x0, y0, tu_width, tu_height);
508
149k
        int start, end;
509
510
149k
        if (!tu)
511
0
            return AVERROR_INVALIDDATA;
512
149k
        ff_vvc_channel_range(&start, &end, cu->tree_type, sps->r->sps_chroma_format_idc);
513
405k
        for (int i = start; i < end; i++) {
514
255k
            TransformBlock *tb = add_tb(tu, lc, x0, y0, tu_width >> sps->hshift[i], tu_height >> sps->vshift[i], i);
515
255k
            if (i != CR)
516
202k
                set_tb_size(fc, tb);
517
255k
        }
518
149k
    }
519
520
149k
    return 0;
521
149k
}
522
523
//6.4.1 Allowed quad split process
524
//6.4.2 Allowed binary split process
525
//6.4.3 Allowed ternary split process
526
static void can_split(const VVCLocalContext *lc, int x0, int y0,int cb_width, int cb_height,
527
     int mtt_depth, int depth_offset, int part_idx, VVCSplitMode last_split_mode,
528
     VVCTreeType tree_type, VVCModeType mode_type, VVCAllowedSplit* split)
529
19.7M
{
530
19.7M
    int min_qt_size, max_bt_size, max_tt_size, max_mtt_depth;
531
19.7M
    const VVCFrameContext *fc   = lc->fc;
532
19.7M
    const VVCSH *sh             = &lc->sc->sh;
533
19.7M
    const VVCSPS *sps           = fc->ps.sps;
534
19.7M
    const VVCPPS *pps           = fc->ps.pps;
535
19.7M
    const int chroma            = tree_type == DUAL_TREE_CHROMA;
536
19.7M
    int min_cb_size_y           = sps->min_cb_size_y;
537
19.7M
    int *qt                     = &split->qt;
538
19.7M
    int *btv                    = &split->btv;
539
19.7M
    int *bth                    = &split->bth;
540
19.7M
    int *ttv                    = &split->ttv;
541
19.7M
    int *tth                    = &split->tth;
542
543
19.7M
    *qt = *bth = *btv = *tth = *ttv = 1;
544
545
19.7M
    if (mtt_depth)
546
6.16M
        *qt = 0;
547
548
19.7M
    min_qt_size = sh->min_qt_size[chroma];
549
19.7M
    if (cb_width <= min_qt_size)
550
7.08M
        *qt = 0;
551
552
19.7M
    if (chroma) {
553
5.96M
        int chroma_area = (cb_width >> sps->hshift[1]) * (cb_height >> sps->vshift[1]);
554
5.96M
        int chroma_width = cb_width >> sps->hshift[1];
555
556
5.96M
        if (chroma_width == 8)
557
1.36M
            *ttv = 0;
558
4.60M
        else if (chroma_width <= 4) {
559
1.18M
            if (chroma_width == 4)
560
1.18M
                *btv = 0;
561
1.18M
            *qt = 0;
562
1.18M
        }
563
5.96M
        if (mode_type == MODE_TYPE_INTRA)
564
283k
            *qt = *btv = *bth = *ttv = *tth = 0;
565
5.96M
        if (chroma_area <= 32) {
566
1.48M
            *ttv = *tth = 0;
567
1.48M
            if (chroma_area <= 16)
568
1.14M
                *btv = *bth = 0;
569
1.48M
        }
570
5.96M
    }
571
19.7M
    max_bt_size = sh->max_bt_size[chroma];
572
19.7M
    max_tt_size = sh->max_tt_size[chroma];
573
19.7M
    max_mtt_depth = sh->max_mtt_depth[chroma] + depth_offset;
574
575
19.7M
    if (mode_type == MODE_TYPE_INTER) {
576
25.2k
        int area = cb_width * cb_height;
577
25.2k
        if (area == 32)
578
25.1k
            *btv = *bth = 0;
579
85
        else if (area == 64)
580
69
            *ttv = *tth = 0;
581
25.2k
    }
582
19.7M
    if (cb_width <= 2 * min_cb_size_y) {
583
7.83M
        *ttv = 0;
584
7.83M
        if (cb_width <= min_cb_size_y)
585
3.86M
            *btv = 0;
586
7.83M
    }
587
19.7M
    if (cb_height <= 2 * min_cb_size_y) {
588
8.97M
        *tth = 0;
589
8.97M
        if (cb_height <= min_cb_size_y)
590
4.49M
            *bth = 0;
591
8.97M
    }
592
19.7M
    if (cb_width > max_bt_size || cb_height > max_bt_size)
593
8.10M
        *btv = *bth = 0;
594
19.7M
    max_tt_size = FFMIN(64, max_tt_size);
595
19.7M
    if (cb_width > max_tt_size || cb_height > max_tt_size)
596
8.21M
        *ttv = *tth = 0;
597
19.7M
    if (mtt_depth >= max_mtt_depth)
598
9.59M
        *btv = *bth = *ttv = *tth = 0;
599
19.7M
    if (x0 + cb_width > pps->width) {
600
6.71M
        *ttv = *tth = 0;
601
6.71M
        if (cb_height > 64)
602
16.8k
            *btv = 0;
603
6.71M
        if (y0 + cb_height <= pps->height)
604
483k
            *bth = 0;
605
6.22M
        else if (cb_width > min_qt_size)
606
5.59M
            *btv = *bth = 0;
607
6.71M
    }
608
19.7M
    if (y0 + cb_height > pps->height) {
609
6.46M
        *btv = *ttv = *tth = 0;
610
6.46M
        if (cb_width > 64)
611
16.8k
            *bth = 0;
612
6.46M
    }
613
19.7M
    if (mtt_depth > 0 && part_idx  == 1)  {
614
2.37M
        if (last_split_mode == SPLIT_TT_VER)
615
167k
            *btv = 0;
616
2.20M
        else if (last_split_mode == SPLIT_TT_HOR)
617
180k
            *bth = 0;
618
2.37M
    }
619
19.7M
    if (cb_width <= 64 && cb_height > 64)
620
4
        *btv = 0;
621
19.7M
    if (cb_width > 64 && cb_height <= 64)
622
4
        *bth = 0;
623
19.7M
}
624
625
static int get_num_intra_subpartitions(enum IspType isp_split_type, int cb_width, int cb_height)
626
5.34M
{
627
5.34M
    if (isp_split_type == ISP_NO_SPLIT)
628
5.26M
        return 1;
629
85.8k
    if ((cb_width == 4 && cb_height == 8) || (cb_width == 8 && cb_height == 4))
630
26.1k
        return 2;
631
59.7k
    return 4;
632
85.8k
}
633
634
static int get_cclm_enabled(const VVCLocalContext *lc, const int x0, const int y0)
635
3.48M
{
636
3.48M
    const VVCFrameContext *fc = lc->fc;
637
3.48M
    const VVCSPS *sps   = fc->ps.sps;
638
3.48M
    int enabled = 0;
639
640
3.48M
    if (!sps->r->sps_cclm_enabled_flag)
641
705k
        return 0;
642
2.77M
    if (!sps->r->sps_qtbtt_dual_tree_intra_flag || !IS_I(lc->sc->sh.r) || sps->ctb_log2_size_y < 6)
643
723k
        return 1;
644
2.05M
    else {
645
2.05M
        const int x64 = x0 >> 6 << 6;
646
2.05M
        const int y64 = y0 >> 6 << 6;
647
2.05M
        const int y32 = y0 >> 5 << 5;
648
2.05M
        const int x64_cu = x64 >> fc->ps.sps->min_cb_log2_size_y;
649
2.05M
        const int y64_cu = y64 >> fc->ps.sps->min_cb_log2_size_y;
650
2.05M
        const int y32_cu = y32 >> fc->ps.sps->min_cb_log2_size_y;
651
2.05M
        const int min_cb_width = fc->ps.pps->min_cb_width;
652
2.05M
        const int depth = SAMPLE_CTB(fc->tab.cqt_depth[1], x64_cu, y64_cu);
653
2.05M
        const int min_depth = fc->ps.sps->ctb_log2_size_y - 6;
654
2.05M
        const VVCSplitMode msm64 = (VVCSplitMode)TAB_MSM(fc, 0, x64, y64);
655
2.05M
        const VVCSplitMode msm32 = (VVCSplitMode)TAB_MSM(fc, 1, x64, y32);
656
657
2.05M
        enabled = SAMPLE_CTB(fc->tab.cb_width[1], x64_cu, y64_cu) == 64 &&
658
188k
            SAMPLE_CTB(fc->tab.cb_height[1], x64_cu, y64_cu) == 64;
659
2.05M
        enabled |= depth == min_depth && msm64 == SPLIT_BT_HOR &&
660
86.4k
            SAMPLE_CTB(fc->tab.cb_width[1], x64_cu, y32_cu) == 64 &&
661
65.6k
            SAMPLE_CTB(fc->tab.cb_height[1], x64_cu, y32_cu) == 32;
662
2.05M
        enabled |= depth > min_depth;
663
2.05M
        enabled |= depth == min_depth && msm64 == SPLIT_BT_HOR && msm32 == SPLIT_BT_VER;
664
665
2.05M
        if (enabled) {
666
1.98M
            const int w = SAMPLE_CTB(fc->tab.cb_width[0], x64_cu, y64_cu);
667
1.98M
            const int h = SAMPLE_CTB(fc->tab.cb_height[0], x64_cu, y64_cu);
668
1.98M
            const int depth0 = SAMPLE_CTB(fc->tab.cqt_depth[0], x64_cu, y64_cu);
669
1.98M
            if ((w == 64 && h == 64 && TAB_ISPMF(fc, x64, y64)) ||
670
1.97M
                ((w < 64 || h < 64) && depth0 == min_depth))
671
11.0k
                return 0;
672
1.98M
        }
673
674
2.05M
    }
675
676
2.04M
    return enabled;
677
2.77M
}
678
679
static int less(const void *a, const void *b)
680
8.10M
{
681
8.10M
    return *(const int*)a - *(const int*)b;
682
8.10M
}
683
684
//8.4.2 Derivation process for luma intra prediction mode
685
static enum IntraPredMode luma_intra_pred_mode(VVCLocalContext* lc, const int intra_subpartitions_mode_flag)
686
5.34M
{
687
5.34M
    VVCFrameContext *fc     = lc->fc;
688
5.34M
    CodingUnit *cu          = lc->cu;
689
5.34M
    const int x0            = cu->x0;
690
5.34M
    const int y0            = cu->y0;
691
5.34M
    enum IntraPredMode pred;
692
5.34M
    int intra_luma_not_planar_flag = 1;
693
5.34M
    int intra_luma_mpm_remainder = 0;
694
5.34M
    int intra_luma_mpm_flag = 1;
695
5.34M
    int intra_luma_mpm_idx = 0;
696
697
5.34M
    if (!cu->intra_luma_ref_idx)
698
5.29M
        intra_luma_mpm_flag = ff_vvc_intra_luma_mpm_flag(lc);
699
5.34M
    if (intra_luma_mpm_flag) {
700
4.18M
        if (!cu->intra_luma_ref_idx)
701
4.12M
            intra_luma_not_planar_flag = ff_vvc_intra_luma_not_planar_flag(lc, intra_subpartitions_mode_flag);
702
4.18M
        if (intra_luma_not_planar_flag)
703
2.16M
            intra_luma_mpm_idx = ff_vvc_intra_luma_mpm_idx(lc);
704
4.18M
    } else {
705
1.16M
        intra_luma_mpm_remainder = ff_vvc_intra_luma_mpm_remainder(lc);
706
1.16M
    }
707
708
5.34M
    if (!intra_luma_not_planar_flag) {
709
2.01M
        pred = INTRA_PLANAR;
710
3.33M
    } else {
711
3.33M
        const VVCSPS *sps       = fc->ps.sps;
712
3.33M
        const int x_a           = (x0 - 1) >> sps->min_cb_log2_size_y;
713
3.33M
        const int y_a           = (y0 + cu->cb_height - 1) >> sps->min_cb_log2_size_y;
714
3.33M
        const int x_b           = (x0 + cu->cb_width - 1) >> sps->min_cb_log2_size_y;
715
3.33M
        const int y_b           = (y0 - 1) >> sps->min_cb_log2_size_y;
716
3.33M
        int min_cb_width        = fc->ps.pps->min_cb_width;
717
3.33M
        int x0b                 = av_zero_extend(x0, sps->ctb_log2_size_y);
718
3.33M
        int y0b                 = av_zero_extend(y0, sps->ctb_log2_size_y);
719
3.33M
        const int available_l   = lc->ctb_left_flag || x0b;
720
3.33M
        const int available_u   = lc->ctb_up_flag || y0b;
721
722
3.33M
        int a, b, cand[5];
723
724
3.33M
       if (!available_l || (SAMPLE_CTB(fc->tab.cpm[0], x_a, y_a) != MODE_INTRA) ||
725
1.71M
            SAMPLE_CTB(fc->tab.imf, x_a, y_a)) {
726
1.64M
            a = INTRA_PLANAR;
727
1.69M
        } else {
728
1.69M
            a = SAMPLE_CTB(fc->tab.ipm, x_a, y_a);
729
1.69M
        }
730
731
3.33M
        if (!available_u || (SAMPLE_CTB(fc->tab.cpm[0], x_b, y_b) != MODE_INTRA) ||
732
1.82M
            SAMPLE_CTB(fc->tab.imf, x_b, y_b) || !y0b) {
733
1.75M
            b = INTRA_PLANAR;
734
1.75M
        } else {
735
1.58M
            b = SAMPLE_CTB(fc->tab.ipm, x_b, y_b);
736
1.58M
        }
737
738
3.33M
        if (a == b && a > INTRA_DC) {
739
99.2k
            cand[0] = a;
740
99.2k
            cand[1] = 2 + ((a + 61) % 64);
741
99.2k
            cand[2] = 2 + ((a -  1) % 64);
742
99.2k
            cand[3] = 2 + ((a + 60) % 64);
743
99.2k
            cand[4] = 2 + (a % 64);
744
3.23M
        } else {
745
3.23M
            const int minab = FFMIN(a, b);
746
3.23M
            const int maxab = FFMAX(a, b);
747
3.23M
            if (a > INTRA_DC && b > INTRA_DC) {
748
395k
                const int diff = maxab - minab;
749
395k
                cand[0] = a;
750
395k
                cand[1] = b;
751
395k
                if (diff == 1) {
752
87.3k
                    cand[2] = 2 + ((minab + 61) % 64);
753
87.3k
                    cand[3] = 2 + ((maxab - 1) % 64);
754
87.3k
                    cand[4] = 2 + ((minab + 60) % 64);
755
307k
                } else if (diff >= 62) {
756
3.02k
                    cand[2] = 2 + ((minab - 1) % 64);
757
3.02k
                    cand[3] = 2 + ((maxab + 61) % 64);
758
3.02k
                    cand[4] = 2 + (minab % 64);
759
304k
                } else if (diff == 2) {
760
45.4k
                    cand[2] = 2 + ((minab - 1) % 64);
761
45.4k
                    cand[3] = 2 + ((minab + 61) % 64);
762
45.4k
                    cand[4] = 2 + ((maxab - 1) % 64);
763
259k
                } else {
764
259k
                    cand[2] = 2 + ((minab + 61) % 64);
765
259k
                    cand[3] = 2 + ((minab - 1) % 64);
766
259k
                    cand[4] = 2 + ((maxab + 61) % 64);
767
259k
                }
768
2.84M
            } else if (a > INTRA_DC || b > INTRA_DC) {
769
986k
                cand[0] = maxab;
770
986k
                cand[1] = 2 + ((maxab + 61 ) % 64);
771
986k
                cand[2] = 2 + ((maxab - 1) % 64);
772
986k
                cand[3] = 2 + ((maxab + 60 ) % 64);
773
986k
                cand[4] = 2 + (maxab % 64);
774
1.85M
            } else {
775
1.85M
                cand[0] = INTRA_DC;
776
1.85M
                cand[1] = INTRA_VERT;
777
1.85M
                cand[2] = INTRA_HORZ;
778
1.85M
                cand[3] = INTRA_VERT - 4;
779
1.85M
                cand[4] = INTRA_VERT + 4;
780
1.85M
            }
781
3.23M
        }
782
3.33M
        if (intra_luma_mpm_flag) {
783
2.16M
            pred = cand[intra_luma_mpm_idx];
784
2.16M
        } else {
785
1.16M
            qsort(cand, FF_ARRAY_ELEMS(cand), sizeof(cand[0]), less);
786
1.16M
            pred = intra_luma_mpm_remainder + 1;
787
7.01M
            for (int i = 0; i < FF_ARRAY_ELEMS(cand); i++) {
788
5.84M
                if (pred >= cand[i])
789
2.83M
                    pred++;
790
5.84M
            }
791
1.16M
        }
792
3.33M
    }
793
5.34M
    return pred;
794
5.34M
}
795
796
static int lfnst_idx_decode(VVCLocalContext *lc)
797
9.17M
{
798
9.17M
    CodingUnit  *cu             = lc->cu;
799
9.17M
    const VVCTreeType tree_type = cu->tree_type;
800
9.17M
    const VVCSPS *sps           = lc->fc->ps.sps;
801
9.17M
    const int cb_width          = cu->cb_width;
802
9.17M
    const int cb_height         = cu->cb_height;
803
9.17M
    const TransformUnit  *tu    = cu->tus.head;
804
9.17M
    int lfnst_width, lfnst_height, min_lfnst;
805
9.17M
    int lfnst_idx = 0;
806
807
9.17M
    memset(cu->apply_lfnst_flag, 0, sizeof(cu->apply_lfnst_flag));
808
809
9.17M
    if (!sps->r->sps_lfnst_enabled_flag || cu->pred_mode != MODE_INTRA || FFMAX(cb_width, cb_height) > sps->max_tb_size_y)
810
3.50M
        return 0;
811
812
11.1M
    while (tu) {
813
14.0M
        for (int j = 0; j < tu->nb_tbs; j++) {
814
8.58M
            const TransformBlock *tb = tu->tbs + j;
815
8.58M
            if (tu->coded_flag[tb->c_idx] && tb->ts)
816
281k
                return 0;
817
8.58M
        }
818
5.49M
        tu = tu->next;
819
5.49M
    }
820
821
5.38M
    if (tree_type == DUAL_TREE_CHROMA) {
822
2.15M
        lfnst_width  = cb_width  >> sps->hshift[1];
823
2.15M
        lfnst_height = cb_height >> sps->vshift[1];
824
3.23M
    } else {
825
3.23M
        const int vs = cu->isp_split_type == ISP_VER_SPLIT;
826
3.23M
        const int hs = cu->isp_split_type == ISP_HOR_SPLIT;
827
3.23M
        lfnst_width = vs ? cb_width / cu->num_intra_subpartitions : cb_width;
828
3.23M
        lfnst_height = hs ? cb_height / cu->num_intra_subpartitions : cb_height;
829
3.23M
    }
830
5.38M
    min_lfnst = FFMIN(lfnst_width, lfnst_height);
831
5.38M
    if (tree_type != DUAL_TREE_CHROMA && cu->intra_mip_flag && min_lfnst < 16)
832
130k
        return 0;
833
834
5.25M
    if (min_lfnst >= 4) {
835
5.13M
        if ((cu->isp_split_type != ISP_NO_SPLIT || !lc->parse.lfnst_dc_only) && lc->parse.lfnst_zero_out_sig_coeff_flag)
836
488k
            lfnst_idx = ff_vvc_lfnst_idx(lc, tree_type != SINGLE_TREE);
837
5.13M
    }
838
839
5.25M
    if (lfnst_idx) {
840
385k
        cu->apply_lfnst_flag[LUMA] = tree_type != DUAL_TREE_CHROMA;
841
385k
        cu->apply_lfnst_flag[CB] = cu->apply_lfnst_flag[CR] = tree_type == DUAL_TREE_CHROMA;
842
385k
    }
843
844
5.25M
    return lfnst_idx;
845
5.38M
}
846
847
static MtsIdx mts_idx_decode(VVCLocalContext *lc)
848
9.17M
{
849
9.17M
    const CodingUnit *cu    = lc->cu;
850
9.17M
    const VVCSPS     *sps   = lc->fc->ps.sps;
851
9.17M
    const int cb_width      = cu->cb_width;
852
9.17M
    const int cb_height     = cu->cb_height;
853
9.17M
    const uint8_t transform_skip_flag = cu->tus.head->tbs[0].ts; //fix me
854
9.17M
    int mts_idx = MTS_DCT2_DCT2;
855
9.17M
    if (cu->tree_type != DUAL_TREE_CHROMA && !cu->lfnst_idx &&
856
5.98M
        !transform_skip_flag && FFMAX(cb_width, cb_height) <= 32 &&
857
5.30M
        cu->isp_split_type == ISP_NO_SPLIT && !cu->sbt_flag &&
858
5.21M
        lc->parse.mts_zero_out_sig_coeff_flag && !lc->parse.mts_dc_only) {
859
3.78M
        if ((cu->pred_mode == MODE_INTER && sps->r->sps_explicit_mts_inter_enabled_flag) ||
860
3.78M
            (cu->pred_mode == MODE_INTRA && sps->r->sps_explicit_mts_intra_enabled_flag)) {
861
1.56M
            mts_idx = ff_vvc_mts_idx(lc);
862
1.56M
        }
863
3.78M
    }
864
865
9.17M
    return mts_idx;
866
9.17M
}
867
868
static enum IntraPredMode derive_center_luma_intra_pred_mode(const VVCFrameContext *fc, const VVCSPS *sps, const VVCPPS *pps, const CodingUnit *cu)
869
3.66M
{
870
3.66M
    const int x_center            = (cu->x0 + cu->cb_width / 2) >> sps->min_cb_log2_size_y;
871
3.66M
    const int y_center            = (cu->y0 + cu->cb_height / 2) >> sps->min_cb_log2_size_y;
872
3.66M
    const int min_cb_width        = pps->min_cb_width;
873
3.66M
    const int intra_mip_flag      = SAMPLE_CTB(fc->tab.imf, x_center, y_center);
874
3.66M
    const int cu_pred_mode        = SAMPLE_CTB(fc->tab.cpm[0], x_center, y_center);
875
3.66M
    const int intra_pred_mode_y   = SAMPLE_CTB(fc->tab.ipm, x_center, y_center);
876
877
3.66M
    if (intra_mip_flag) {
878
104k
        if (cu->tree_type == SINGLE_TREE && sps->r->sps_chroma_format_idc == CHROMA_FORMAT_444)
879
15.2k
            return INTRA_INVALID;
880
89.2k
        return INTRA_PLANAR;
881
104k
    }
882
3.56M
    if (cu_pred_mode == MODE_IBC || cu_pred_mode == MODE_PLT)
883
141k
        return INTRA_DC;
884
3.42M
    return intra_pred_mode_y;
885
3.56M
}
886
887
static void derive_chroma_intra_pred_mode(VVCLocalContext *lc,
888
    const int cclm_mode_flag, const int cclm_mode_idx, const int intra_chroma_pred_mode)
889
3.68M
{
890
3.68M
    const VVCFrameContext *fc   = lc->fc;
891
3.68M
    CodingUnit *cu              = lc->cu;
892
3.68M
    const VVCSPS *sps           = fc->ps.sps;
893
3.68M
    const VVCPPS *pps           = fc->ps.pps;
894
3.68M
    const int x_cb              = cu->x0 >> sps->min_cb_log2_size_y;
895
3.68M
    const int y_cb              = cu->y0 >> sps->min_cb_log2_size_y;
896
3.68M
    const int min_cb_width      = pps->min_cb_width;
897
3.68M
    const int intra_mip_flag    = SAMPLE_CTB(fc->tab.imf, x_cb, y_cb);
898
3.68M
    enum IntraPredMode luma_intra_pred_mode = SAMPLE_CTB(fc->tab.ipm, x_cb, y_cb);
899
900
3.68M
    if (cu->tree_type == SINGLE_TREE && sps->r->sps_chroma_format_idc == CHROMA_FORMAT_444 &&
901
620k
        (intra_chroma_pred_mode == 4 || cu->act_enabled_flag) && intra_mip_flag) {
902
18.8k
        cu->mip_chroma_direct_flag = 1;
903
18.8k
        cu->intra_pred_mode_c = luma_intra_pred_mode;
904
18.8k
        return;
905
18.8k
    }
906
3.66M
    luma_intra_pred_mode = derive_center_luma_intra_pred_mode(fc, sps, pps, cu);
907
908
3.66M
    if (cu->act_enabled_flag) {
909
201k
        cu->intra_pred_mode_c = luma_intra_pred_mode;
910
201k
        return;
911
201k
    }
912
3.46M
    if (cclm_mode_flag) {
913
1.79M
        cu->intra_pred_mode_c = INTRA_LT_CCLM + cclm_mode_idx;
914
1.79M
    } else if (intra_chroma_pred_mode == 4){
915
1.39M
        cu->intra_pred_mode_c = luma_intra_pred_mode;
916
1.39M
    } else {
917
275k
        const static IntraPredMode pred_mode_c[][4 + 1] = {
918
275k
            {INTRA_VDIAG, INTRA_PLANAR, INTRA_PLANAR, INTRA_PLANAR, INTRA_PLANAR},
919
275k
            {INTRA_VERT,  INTRA_VDIAG,  INTRA_VERT,   INTRA_VERT,   INTRA_VERT},
920
275k
            {INTRA_HORZ,  INTRA_HORZ,   INTRA_VDIAG,  INTRA_HORZ,   INTRA_HORZ},
921
275k
            {INTRA_DC,    INTRA_DC,     INTRA_DC,     INTRA_VDIAG,  INTRA_DC},
922
275k
        };
923
275k
        const int modes[4] = {INTRA_PLANAR, INTRA_VERT, INTRA_HORZ, INTRA_DC};
924
275k
        int idx;
925
926
        // This workaround is necessary to have 4:4:4 video decode correctly
927
        // See VVC ticket https://jvet.hhi.fraunhofer.de/trac/vvc/ticket/1602
928
        // and VTM source https://vcgit.hhi.fraunhofer.de/jvet/VVCSoftware_VTM/-/blob/master/source/Lib/CommonLib/UnitTools.cpp#L736
929
275k
        if (cu->tree_type == SINGLE_TREE && sps->r->sps_chroma_format_idc == CHROMA_FORMAT_444 && intra_mip_flag) {
930
1.54k
            idx = 4;
931
273k
        } else {
932
835k
            for (idx = 0; idx < FF_ARRAY_ELEMS(modes); idx++) {
933
767k
                if (modes[idx] == luma_intra_pred_mode)
934
205k
                    break;
935
767k
            }
936
273k
        }
937
938
275k
        cu->intra_pred_mode_c = pred_mode_c[intra_chroma_pred_mode][idx];
939
275k
    }
940
3.46M
    if (sps->r->sps_chroma_format_idc == CHROMA_FORMAT_422 && cu->intra_pred_mode_c <= INTRA_VDIAG) {
941
12.7k
        const static int mode_map_422[INTRA_VDIAG + 1] = {
942
12.7k
             0,  1, 61, 62, 63, 64, 65, 66,  2,  3,  5,  6,  8, 10, 12, 13,
943
12.7k
            14, 16, 18, 20, 22, 23, 24, 26, 28, 30, 31, 33, 34, 35, 36, 37,
944
12.7k
            38, 39, 40, 41, 41, 42, 43, 43, 44, 44, 45, 45, 46, 47, 48, 48,
945
12.7k
            49, 49, 50, 51, 51, 52, 52, 53, 54, 55, 55, 56, 56, 57, 57, 58,
946
12.7k
            59, 59, 60,
947
12.7k
        };
948
12.7k
        cu->intra_pred_mode_c = mode_map_422[cu->intra_pred_mode_c];
949
12.7k
    }
950
3.46M
}
951
952
static av_always_inline uint8_t pack_mip_info(int intra_mip_flag,
953
    int intra_mip_transposed_flag, int intra_mip_mode)
954
366k
{
955
366k
    return (intra_mip_mode << 2) | (intra_mip_transposed_flag << 1) | intra_mip_flag;
956
366k
}
957
958
static void intra_luma_pred_modes(VVCLocalContext *lc)
959
5.95M
{
960
5.95M
    VVCFrameContext *fc             = lc->fc;
961
5.95M
    const VVCSPS *sps               = fc->ps.sps;
962
5.95M
    const VVCPPS *pps               = fc->ps.pps;
963
5.95M
    CodingUnit *cu                  = lc->cu;
964
5.95M
    const int log2_min_cb_size      = sps->min_cb_log2_size_y;
965
5.95M
    const int x0                    = cu->x0;
966
5.95M
    const int y0                    = cu->y0;
967
5.95M
    const int x_cb                  = x0 >> log2_min_cb_size;
968
5.95M
    const int y_cb                  = y0 >> log2_min_cb_size;
969
5.95M
    const int cb_width              = cu->cb_width;
970
5.95M
    const int cb_height             = cu->cb_height;
971
972
5.95M
    cu->intra_luma_ref_idx  = 0;
973
5.95M
    if (sps->r->sps_bdpcm_enabled_flag && cb_width <= sps->max_ts_size && cb_height <= sps->max_ts_size)
974
1.25M
        cu->bdpcm_flag[LUMA] = ff_vvc_intra_bdpcm_luma_flag(lc);
975
5.95M
    if (cu->bdpcm_flag[LUMA]) {
976
291k
        cu->intra_pred_mode_y = ff_vvc_intra_bdpcm_luma_dir_flag(lc) ? INTRA_VERT : INTRA_HORZ;
977
5.65M
    } else {
978
5.65M
        if (sps->r->sps_mip_enabled_flag)
979
2.59M
            cu->intra_mip_flag = ff_vvc_intra_mip_flag(lc, fc->tab.imf);
980
5.65M
        if (cu->intra_mip_flag) {
981
308k
            int intra_mip_transposed_flag = ff_vvc_intra_mip_transposed_flag(lc);
982
308k
            int intra_mip_mode = ff_vvc_intra_mip_mode(lc);
983
308k
            int x = y_cb * pps->min_cb_width + x_cb;
984
674k
            for (int y = 0; y < (cb_height>>log2_min_cb_size); y++) {
985
366k
                int width = cb_width>>log2_min_cb_size;
986
366k
                const uint8_t mip_info = pack_mip_info(cu->intra_mip_flag,
987
366k
                        intra_mip_transposed_flag, intra_mip_mode);
988
366k
                memset(&fc->tab.imf[x], mip_info, width);
989
366k
                x += pps->min_cb_width;
990
366k
            }
991
308k
            cu->intra_pred_mode_y = intra_mip_mode;
992
5.34M
        } else {
993
5.34M
            int intra_subpartitions_mode_flag = 0;
994
5.34M
            if (sps->r->sps_mrl_enabled_flag && ((y0 % sps->ctb_size_y) > 0))
995
1.70M
                cu->intra_luma_ref_idx = ff_vvc_intra_luma_ref_idx(lc);
996
5.34M
            if (sps->r->sps_isp_enabled_flag && !cu->intra_luma_ref_idx &&
997
3.51M
                (cb_width <= sps->max_tb_size_y && cb_height <= sps->max_tb_size_y) &&
998
3.51M
                (cb_width * cb_height > MIN_TU_SIZE * MIN_TU_SIZE) &&
999
1.91M
                !cu->act_enabled_flag)
1000
1.88M
                intra_subpartitions_mode_flag = ff_vvc_intra_subpartitions_mode_flag(lc);
1001
5.34M
            if (!(x0 & 63) && !(y0 & 63))
1002
1.43M
                TAB_ISPMF(fc, x0, y0) = intra_subpartitions_mode_flag;
1003
5.34M
            cu->isp_split_type = ff_vvc_isp_split_type(lc, intra_subpartitions_mode_flag);
1004
5.34M
            cu->num_intra_subpartitions = get_num_intra_subpartitions(cu->isp_split_type, cb_width, cb_height);
1005
5.34M
            cu->intra_pred_mode_y = luma_intra_pred_mode(lc, intra_subpartitions_mode_flag);
1006
5.34M
        }
1007
5.65M
    }
1008
5.95M
    set_cb_tab(lc, fc->tab.ipm, cu->intra_pred_mode_y);
1009
5.95M
}
1010
1011
static void intra_chroma_pred_modes(VVCLocalContext *lc)
1012
3.70M
{
1013
3.70M
    const VVCSPS *sps          = lc->fc->ps.sps;
1014
3.70M
    CodingUnit *cu             = lc->cu;
1015
3.70M
    const int hs               = sps->hshift[CHROMA];
1016
3.70M
    const int vs               = sps->vshift[CHROMA];
1017
3.70M
    int cclm_mode_flag         = 0;
1018
3.70M
    int cclm_mode_idx          = 0;
1019
3.70M
    int intra_chroma_pred_mode = 0;
1020
1021
3.70M
    if (!cu->act_enabled_flag) {
1022
3.50M
        cu->mip_chroma_direct_flag = 0;
1023
3.50M
        if (sps->r->sps_bdpcm_enabled_flag &&
1024
444k
            (cu->cb_width  >> hs) <= sps->max_ts_size &&
1025
395k
            (cu->cb_height >> vs) <= sps->max_ts_size) {
1026
395k
            cu->bdpcm_flag[CB] = cu->bdpcm_flag[CR] = ff_vvc_intra_bdpcm_chroma_flag(lc);
1027
395k
        }
1028
3.50M
        if (cu->bdpcm_flag[CHROMA]) {
1029
23.9k
            cu->intra_pred_mode_c = ff_vvc_intra_bdpcm_chroma_dir_flag(lc) ? INTRA_VERT : INTRA_HORZ;
1030
3.48M
        } else {
1031
3.48M
            const int cclm_enabled = get_cclm_enabled(lc, cu->x0, cu->y0);
1032
1033
3.48M
            if (cclm_enabled)
1034
2.69M
                cclm_mode_flag = ff_vvc_cclm_mode_flag(lc);
1035
1036
3.48M
            if (cclm_mode_flag)
1037
1.79M
                cclm_mode_idx = ff_vvc_cclm_mode_idx(lc);
1038
1.68M
            else
1039
1.68M
                intra_chroma_pred_mode = ff_vvc_intra_chroma_pred_mode(lc);
1040
3.48M
        }
1041
3.50M
    }
1042
1043
3.70M
    if (!cu->bdpcm_flag[CHROMA])
1044
3.68M
        derive_chroma_intra_pred_mode(lc, cclm_mode_flag, cclm_mode_idx, intra_chroma_pred_mode);
1045
3.70M
}
1046
1047
static PredMode pred_mode_decode(VVCLocalContext *lc,
1048
                                 const VVCTreeType tree_type,
1049
                                 const VVCModeType mode_type)
1050
9.42M
{
1051
9.42M
    const VVCFrameContext *fc       = lc->fc;
1052
9.42M
    CodingUnit *cu                  = lc->cu;
1053
9.42M
    const VVCSPS *sps               = fc->ps.sps;
1054
9.42M
    const H266RawSliceHeader *rsh   = lc->sc->sh.r;
1055
9.42M
    const int ch_type               = tree_type == DUAL_TREE_CHROMA ? 1 : 0;
1056
9.42M
    const int is_4x4                = cu->cb_width == 4 && cu->cb_height == 4;
1057
9.42M
    const int is_128                = cu->cb_width == 128 || cu->cb_height == 128;
1058
9.42M
    const int hs                    = sps->hshift[CHROMA];
1059
9.42M
    const int vs                    = sps->vshift[CHROMA];
1060
9.42M
    int pred_mode_flag;
1061
9.42M
    int pred_mode_ibc_flag;
1062
9.42M
    PredMode pred_mode;
1063
1064
9.42M
    cu->skip_flag = 0;
1065
9.42M
    if (!IS_I(rsh) || sps->r->sps_ibc_enabled_flag) {
1066
4.08M
        if (tree_type != DUAL_TREE_CHROMA &&
1067
3.26M
            ((!is_4x4 && mode_type != MODE_TYPE_INTRA) ||
1068
3.26M
            (sps->r->sps_ibc_enabled_flag && !is_128))) {
1069
3.26M
            cu->skip_flag = ff_vvc_cu_skip_flag(lc, fc->tab.skip);
1070
3.26M
        }
1071
1072
4.08M
        if (is_4x4 || mode_type == MODE_TYPE_INTRA || IS_I(rsh)) {
1073
3.98M
            pred_mode_flag = 1;
1074
3.98M
        } else if (mode_type == MODE_TYPE_INTER || cu->skip_flag) {
1075
32.1k
            pred_mode_flag = 0;
1076
61.0k
        } else  {
1077
61.0k
            pred_mode_flag = ff_vvc_pred_mode_flag(lc, ch_type);
1078
61.0k
        }
1079
4.08M
        pred_mode = pred_mode_flag ? MODE_INTRA : MODE_INTER;
1080
1081
4.08M
        if (((IS_I(rsh) && !cu->skip_flag) ||
1082
224k
            (!IS_I(rsh) && (pred_mode != MODE_INTRA ||
1083
97.2k
            ((is_4x4 || mode_type == MODE_TYPE_INTRA) && !cu->skip_flag)))) &&
1084
4.03M
            !is_128 && mode_type != MODE_TYPE_INTER && sps->r->sps_ibc_enabled_flag &&
1085
3.98M
            tree_type != DUAL_TREE_CHROMA) {
1086
3.17M
            pred_mode_ibc_flag = ff_vvc_pred_mode_ibc_flag(lc, ch_type);
1087
3.17M
        } else if (cu->skip_flag && (is_4x4 || mode_type == MODE_TYPE_INTRA)) {
1088
36.2k
            pred_mode_ibc_flag = 1;
1089
875k
        } else if (is_128 || mode_type == MODE_TYPE_INTER || tree_type == DUAL_TREE_CHROMA) {
1090
841k
            pred_mode_ibc_flag = 0;
1091
841k
        } else {
1092
34.2k
            pred_mode_ibc_flag = (IS_I(rsh)) ? sps->r->sps_ibc_enabled_flag : 0;
1093
34.2k
        }
1094
4.08M
        if (pred_mode_ibc_flag)
1095
355k
            pred_mode = MODE_IBC;
1096
5.34M
    } else {
1097
5.34M
        pred_mode = MODE_INTRA;
1098
5.34M
    }
1099
1100
9.42M
    if (pred_mode == MODE_INTRA && sps->r->sps_palette_enabled_flag && !is_128 && !cu->skip_flag &&
1101
2.21M
        mode_type != MODE_TYPE_INTER && ((cu->cb_width * cu->cb_height) >
1102
2.21M
            (tree_type != DUAL_TREE_CHROMA ? 16 : (16 << hs << vs))) &&
1103
835k
        (mode_type != MODE_TYPE_INTRA || tree_type != DUAL_TREE_CHROMA)) {
1104
834k
        if (ff_vvc_pred_mode_plt_flag(lc))
1105
77.6k
            pred_mode = MODE_PLT;
1106
834k
    }
1107
1108
9.42M
    set_cb_tab(lc, fc->tab.cpm[cu->ch_type], pred_mode);
1109
9.42M
    if (tree_type == SINGLE_TREE)
1110
927k
        set_cb_tab(lc, fc->tab.cpm[CHROMA], pred_mode);
1111
1112
9.42M
    return pred_mode;
1113
9.42M
}
1114
1115
static void sbt_info(VVCLocalContext *lc, const VVCSPS *sps)
1116
9.18M
{
1117
9.18M
    CodingUnit *cu      = lc->cu;
1118
9.18M
    const int cb_width  = cu->cb_width;
1119
9.18M
    const int cb_height = cu->cb_height;
1120
1121
9.18M
    if (cu->pred_mode == MODE_INTER && sps->r->sps_sbt_enabled_flag && !cu->ciip_flag
1122
22.9k
        && cb_width <= sps->max_tb_size_y && cb_height <= sps->max_tb_size_y) {
1123
22.9k
        const int sbt_ver_h = cb_width  >= 8;
1124
22.9k
        const int sbt_hor_h = cb_height >= 8;
1125
22.9k
        cu->sbt_flag = 0;
1126
22.9k
        if (sbt_ver_h || sbt_hor_h)
1127
22.9k
            cu->sbt_flag = ff_vvc_sbt_flag(lc);
1128
22.9k
        if (cu->sbt_flag) {
1129
6.53k
            const int sbt_ver_q = cb_width  >= 16;
1130
6.53k
            const int sbt_hor_q = cb_height >= 16;
1131
6.53k
            int cu_sbt_quad_flag = 0;
1132
1133
6.53k
            if ((sbt_ver_h || sbt_hor_h) && (sbt_ver_q || sbt_hor_q))
1134
0
                cu_sbt_quad_flag = ff_vvc_sbt_quad_flag(lc);
1135
6.53k
            if (cu_sbt_quad_flag) {
1136
0
                cu->sbt_horizontal_flag = sbt_hor_q;
1137
0
                if (sbt_ver_q && sbt_hor_q)
1138
0
                    cu->sbt_horizontal_flag = ff_vvc_sbt_horizontal_flag(lc);
1139
6.53k
            } else {
1140
6.53k
                cu->sbt_horizontal_flag = sbt_hor_h;
1141
6.53k
                if (sbt_ver_h && sbt_hor_h)
1142
5.50k
                    cu->sbt_horizontal_flag = ff_vvc_sbt_horizontal_flag(lc);
1143
6.53k
            }
1144
6.53k
            cu->sbt_pos_flag = ff_vvc_sbt_pos_flag(lc);
1145
1146
6.53k
            {
1147
6.53k
                const int sbt_min = cu_sbt_quad_flag ? 1 : 2;
1148
6.53k
                lc->parse.sbt_num_fourths_tb0 = cu->sbt_pos_flag ? (4 - sbt_min) : sbt_min;
1149
6.53k
            }
1150
6.53k
        }
1151
22.9k
    }
1152
9.18M
}
1153
1154
static int skipped_transform_tree_unit(VVCLocalContext *lc)
1155
149k
{
1156
149k
    const H266RawSPS *rsps = lc->fc->ps.sps->r;
1157
149k
    const CodingUnit *cu   = lc->cu;
1158
149k
    int ret;
1159
1160
149k
    if (cu->tree_type != DUAL_TREE_CHROMA) {
1161
149k
        ret = set_qp_y(lc, cu->x0, cu->y0, 0);
1162
149k
        if (ret < 0)
1163
0
            return ret;
1164
149k
    }
1165
149k
    if (rsps->sps_chroma_format_idc && cu->tree_type != DUAL_TREE_LUMA)
1166
52.6k
        set_qp_c(lc);
1167
149k
    ret = skipped_transform_tree(lc, cu->x0, cu->y0, cu->cb_width, cu->cb_height);
1168
149k
    if (ret < 0)
1169
0
        return ret;
1170
149k
    return 0;
1171
149k
}
1172
1173
static void set_cb_pos(const VVCFrameContext *fc, const CodingUnit *cu)
1174
9.42M
{
1175
9.42M
    const VVCSPS *sps           = fc->ps.sps;
1176
9.42M
    const VVCPPS *pps           = fc->ps.pps;
1177
9.42M
    const int log2_min_cb_size  = sps->min_cb_log2_size_y;
1178
9.42M
    const int x_cb              = cu->x0 >> log2_min_cb_size;
1179
9.42M
    const int y_cb              = cu->y0 >> log2_min_cb_size;
1180
9.42M
    const int ch_type           = cu->ch_type;
1181
9.42M
    int x, y;
1182
1183
9.42M
    x = y_cb * pps->min_cb_width + x_cb;
1184
40.3M
    for (y = 0; y < (cu->cb_height >> log2_min_cb_size); y++) {
1185
30.9M
        const int width = cu->cb_width >> log2_min_cb_size;
1186
1187
245M
        for (int i = 0; i < width; i++) {
1188
214M
            fc->tab.cb_pos_x[ch_type][x + i] = cu->x0;
1189
214M
            fc->tab.cb_pos_y[ch_type][x + i] = cu->y0;
1190
214M
        }
1191
30.9M
        memset(&fc->tab.cb_width[ch_type][x], cu->cb_width, width);
1192
30.9M
        memset(&fc->tab.cb_height[ch_type][x], cu->cb_height, width);
1193
30.9M
        memset(&fc->tab.cqt_depth[ch_type][x], cu->cqt_depth, width);
1194
1195
30.9M
        x += pps->min_cb_width;
1196
30.9M
    }
1197
9.42M
}
1198
1199
static CodingUnit* alloc_cu(VVCLocalContext *lc, const int x0, const int y0)
1200
9.42M
{
1201
9.42M
    VVCFrameContext *fc = lc->fc;
1202
9.42M
    const VVCSPS *sps   = fc->ps.sps;
1203
9.42M
    const VVCPPS *pps   = fc->ps.pps;
1204
9.42M
    const int rx        = x0 >> sps->ctb_log2_size_y;
1205
9.42M
    const int ry        = y0 >> sps->ctb_log2_size_y;
1206
9.42M
    CodingUnit **cus    = fc->tab.cus + ry * pps->ctb_width + rx;
1207
9.42M
    CodingUnit *cu      = av_refstruct_pool_get(fc->cu_pool);
1208
1209
9.42M
    if (!cu)
1210
0
        return NULL;
1211
9.42M
    cu->next = NULL;
1212
1213
9.42M
    if (lc->cu)
1214
7.84M
        lc->cu->next = cu;
1215
1.57M
    else
1216
1.57M
        *cus = cu;
1217
9.42M
    lc->cu = cu;
1218
1219
9.42M
    return cu;
1220
9.42M
}
1221
1222
static CodingUnit* add_cu(VVCLocalContext *lc, const int x0, const int y0,
1223
    const int cb_width, const int cb_height, const int cqt_depth, const VVCTreeType tree_type)
1224
9.42M
{
1225
9.42M
    VVCFrameContext *fc = lc->fc;
1226
9.42M
    const int ch_type   = tree_type == DUAL_TREE_CHROMA ? 1 : 0;
1227
9.42M
    CodingUnit *cu      = alloc_cu(lc, x0, y0);
1228
1229
9.42M
    if (!cu)
1230
0
        return NULL;
1231
1232
9.42M
    memset(&cu->pu, 0, sizeof(cu->pu));
1233
1234
9.42M
    lc->parse.prev_tu_cbf_y = 0;
1235
1236
9.42M
    cu->sbt_flag = 0;
1237
9.42M
    cu->act_enabled_flag = 0;
1238
1239
9.42M
    cu->tree_type = tree_type;
1240
9.42M
    cu->x0 = x0;
1241
9.42M
    cu->y0 = y0;
1242
9.42M
    cu->cb_width = cb_width;
1243
9.42M
    cu->cb_height = cb_height;
1244
9.42M
    cu->ch_type = ch_type;
1245
9.42M
    cu->cqt_depth = cqt_depth;
1246
9.42M
    cu->tus.head = cu->tus.tail = NULL;
1247
9.42M
    cu->bdpcm_flag[LUMA] = cu->bdpcm_flag[CB] = cu->bdpcm_flag[CR] = 0;
1248
9.42M
    cu->isp_split_type = ISP_NO_SPLIT;
1249
9.42M
    cu->intra_mip_flag = 0;
1250
9.42M
    cu->ciip_flag = 0;
1251
9.42M
    cu->coded_flag = 1;
1252
9.42M
    cu->num_intra_subpartitions = 1;
1253
9.42M
    cu->pu.dmvr_flag = 0;
1254
1255
9.42M
    set_cb_pos(fc, cu);
1256
9.42M
    return cu;
1257
9.42M
}
1258
1259
static void set_cu_tabs(const VVCLocalContext *lc, const CodingUnit *cu)
1260
9.39M
{
1261
9.39M
    const VVCFrameContext *fc = lc->fc;
1262
9.39M
    const PredictionUnit *pu  = &cu->pu;
1263
9.39M
    const TransformUnit *tu   = cu->tus.head;
1264
1265
9.39M
    set_cb_tab(lc, fc->tab.mmi, pu->mi.motion_model_idc);
1266
9.39M
    set_cb_tab(lc, fc->tab.msf, pu->merge_subblock_flag);
1267
9.39M
    if (cu->tree_type != DUAL_TREE_CHROMA) {
1268
6.39M
        set_cb_tab(lc, fc->tab.skip, cu->skip_flag);
1269
6.39M
        set_cb_tab(lc, fc->tab.pcmf[LUMA], cu->bdpcm_flag[LUMA]);
1270
6.39M
    }
1271
9.39M
    if (cu->tree_type != DUAL_TREE_LUMA)
1272
3.92M
        set_cb_tab(lc, fc->tab.pcmf[CHROMA], cu->bdpcm_flag[CHROMA]);
1273
1274
19.0M
    while (tu) {
1275
24.0M
          for (int j = 0; j < tu->nb_tbs; j++) {
1276
14.4M
            const TransformBlock *tb = tu->tbs + j;
1277
14.4M
            if (tb->c_idx != LUMA)
1278
7.82M
                set_qp_c_tab(lc, tu, tb);
1279
14.4M
        }
1280
9.60M
        tu = tu->next;
1281
9.60M
    }
1282
9.39M
}
1283
1284
//8.5.2.7 Derivation process for merge motion vector difference
1285
static void derive_mmvd(const VVCLocalContext *lc, MvField *mvf, const Mv *mmvd_offset)
1286
19.4k
{
1287
19.4k
    const SliceContext *sc  = lc->sc;
1288
19.4k
    Mv mmvd[2];
1289
1290
19.4k
    if (mvf->pred_flag == PF_BI) {
1291
15.0k
        const RefPicList *rpl = sc->rpl;
1292
15.0k
        const int poc = lc->fc->ps.ph.poc;
1293
15.0k
        const int diff[] = {
1294
15.0k
            poc - rpl[L0].refs[mvf->ref_idx[L0]].poc,
1295
15.0k
            poc - rpl[L1].refs[mvf->ref_idx[L1]].poc
1296
15.0k
        };
1297
15.0k
        const int sign = FFSIGN(diff[0]) != FFSIGN(diff[1]);
1298
1299
15.0k
        if (diff[0] == diff[1]) {
1300
4.05k
            mmvd[1] = mmvd[0] = *mmvd_offset;
1301
4.05k
        }
1302
11.0k
        else {
1303
11.0k
            const int i = FFABS(diff[0]) < FFABS(diff[1]);
1304
11.0k
            const int o = !i;
1305
11.0k
            mmvd[i] = *mmvd_offset;
1306
11.0k
            if (!rpl[L0].refs[mvf->ref_idx[L0]].is_lt && !rpl[L1].refs[mvf->ref_idx[L1]].is_lt) {
1307
4.27k
                ff_vvc_mv_scale(&mmvd[o], mmvd_offset, diff[i], diff[o]);
1308
4.27k
            }
1309
6.75k
            else {
1310
6.75k
                mmvd[o].x = sign ? -mmvd[i].x : mmvd[i].x;
1311
6.75k
                mmvd[o].y = sign ? -mmvd[i].y : mmvd[i].y;
1312
6.75k
            }
1313
11.0k
        }
1314
15.0k
        mvf->mv[0].x += mmvd[0].x;
1315
15.0k
        mvf->mv[0].y += mmvd[0].y;
1316
15.0k
        mvf->mv[1].x += mmvd[1].x;
1317
15.0k
        mvf->mv[1].y += mmvd[1].y;
1318
15.0k
    } else {
1319
4.33k
        const int idx = mvf->pred_flag - PF_L0;
1320
4.33k
        mvf->mv[idx].x += mmvd_offset->x;
1321
4.33k
        mvf->mv[idx].y += mmvd_offset->y;
1322
4.33k
    }
1323
1324
19.4k
}
1325
1326
static void mvf_to_mi(const MvField *mvf, MotionInfo *mi)
1327
45.5k
{
1328
45.5k
    mi->pred_flag = mvf->pred_flag;
1329
45.5k
    mi->bcw_idx = mvf->bcw_idx;
1330
45.5k
    mi->hpel_if_idx = mvf->hpel_if_idx;
1331
136k
    for (int i = 0; i < 2; i++) {
1332
91.1k
        const PredFlag mask = i + 1;
1333
91.1k
        if (mvf->pred_flag & mask) {
1334
74.3k
            mi->mv[i][0] = mvf->mv[i];
1335
74.3k
            mi->ref_idx[i] = mvf->ref_idx[i];
1336
74.3k
        }
1337
91.1k
    }
1338
45.5k
}
1339
1340
static void mv_merge_refine_pred_flag(MvField *mvf, const int width, const int height)
1341
45.5k
{
1342
45.5k
    if (mvf->pred_flag == PF_BI && (width + height) == 12) {
1343
6.76k
        mvf->pred_flag = PF_L0;
1344
6.76k
        mvf->bcw_idx = 0;
1345
6.76k
    }
1346
45.5k
}
1347
1348
// subblock-based inter prediction data
1349
static void merge_data_subblock(VVCLocalContext *lc)
1350
4.08k
{
1351
4.08k
    const VVCFrameContext *fc   = lc->fc;
1352
4.08k
    const VVCPH  *ph            = &fc->ps.ph;
1353
4.08k
    CodingUnit* cu              = lc->cu;
1354
4.08k
    PredictionUnit *pu          = &cu->pu;
1355
4.08k
    int merge_subblock_idx      = 0;
1356
1357
4.08k
    if (ph->max_num_subblock_merge_cand > 1) {
1358
3.87k
        merge_subblock_idx = ff_vvc_merge_subblock_idx(lc, ph->max_num_subblock_merge_cand);
1359
3.87k
    }
1360
4.08k
    ff_vvc_sb_mv_merge_mode(lc, merge_subblock_idx, pu);
1361
4.08k
}
1362
1363
static void merge_data_regular(VVCLocalContext *lc)
1364
43.3k
{
1365
43.3k
    const VVCFrameContext *fc   = lc->fc;
1366
43.3k
    const VVCSPS *sps           = fc->ps.sps;
1367
43.3k
    const VVCPH  *ph            = &fc->ps.ph;
1368
43.3k
    const CodingUnit* cu        = lc->cu;
1369
43.3k
    PredictionUnit *pu          = &lc->cu->pu;
1370
43.3k
    int merge_idx               = 0;
1371
43.3k
    Mv mmvd_offset;
1372
43.3k
    MvField mvf;
1373
1374
43.3k
    if (sps->r->sps_mmvd_enabled_flag)
1375
38.8k
        pu->mmvd_merge_flag = ff_vvc_mmvd_merge_flag(lc);
1376
43.3k
    if (pu->mmvd_merge_flag) {
1377
19.4k
        int mmvd_cand_flag = 0;
1378
19.4k
        if (sps->max_num_merge_cand > 1)
1379
18.8k
            mmvd_cand_flag = ff_vvc_mmvd_cand_flag(lc);
1380
19.4k
        ff_vvc_mmvd_offset_coding(lc, &mmvd_offset, ph->r->ph_mmvd_fullpel_only_flag);
1381
19.4k
        merge_idx = mmvd_cand_flag;
1382
23.9k
    } else if (sps->max_num_merge_cand > 1) {
1383
23.1k
        merge_idx = ff_vvc_merge_idx(lc);
1384
23.1k
    }
1385
43.3k
    ff_vvc_luma_mv_merge_mode(lc, merge_idx, 0, &mvf);
1386
43.3k
    if (pu->mmvd_merge_flag)
1387
19.4k
        derive_mmvd(lc, &mvf, &mmvd_offset);
1388
43.3k
    mv_merge_refine_pred_flag(&mvf, cu->cb_width, cu->cb_height);
1389
43.3k
    ff_vvc_store_mvf(lc, &mvf);
1390
43.3k
    mvf_to_mi(&mvf, &pu->mi);
1391
43.3k
}
1392
1393
static int ciip_flag_decode(VVCLocalContext *lc, const int ciip_avaiable, const int gpm_avaiable, const int is_128)
1394
11.5k
{
1395
11.5k
    const VVCFrameContext *fc   = lc->fc;
1396
11.5k
    const VVCSPS *sps           = fc->ps.sps;
1397
11.5k
    const CodingUnit *cu        = lc->cu;
1398
1399
11.5k
    if (ciip_avaiable && gpm_avaiable)
1400
4.81k
        return ff_vvc_ciip_flag(lc);
1401
6.74k
    return sps->r->sps_ciip_enabled_flag && !cu->skip_flag &&
1402
1.16k
            !is_128 && (cu->cb_width * cu->cb_height >= 64);
1403
11.5k
}
1404
1405
static void merge_data_gpm(VVCLocalContext *lc)
1406
9.35k
{
1407
9.35k
    const VVCFrameContext *fc   = lc->fc;
1408
9.35k
    const VVCSPS *sps           = fc->ps.sps;
1409
9.35k
    PredictionUnit *pu          = &lc->cu->pu;
1410
9.35k
    int merge_gpm_idx[2];
1411
1412
9.35k
    pu->merge_gpm_flag = 1;
1413
9.35k
    pu->gpm_partition_idx = ff_vvc_merge_gpm_partition_idx(lc);
1414
9.35k
    merge_gpm_idx[0] = ff_vvc_merge_gpm_idx(lc, 0);
1415
9.35k
    merge_gpm_idx[1] = 0;
1416
9.35k
    if (sps->max_num_gpm_merge_cand > 2)
1417
6.66k
        merge_gpm_idx[1] = ff_vvc_merge_gpm_idx(lc, 1);
1418
1419
9.35k
    ff_vvc_luma_mv_merge_gpm(lc, merge_gpm_idx, pu->gpm_mv);
1420
9.35k
    ff_vvc_store_gpm_mvf(lc, pu);
1421
9.35k
}
1422
1423
static void merge_data_ciip(VVCLocalContext *lc)
1424
2.20k
{
1425
2.20k
    const VVCFrameContext* fc   = lc->fc;
1426
2.20k
    const VVCSPS* sps           = fc->ps.sps;
1427
2.20k
    CodingUnit *cu              = lc->cu;
1428
2.20k
    MotionInfo *mi              = &cu->pu.mi;
1429
2.20k
    int merge_idx               = 0;
1430
2.20k
    MvField mvf;
1431
1432
2.20k
    if (sps->max_num_merge_cand > 1)
1433
1.97k
        merge_idx = ff_vvc_merge_idx(lc);
1434
2.20k
    ff_vvc_luma_mv_merge_mode(lc, merge_idx, 1, &mvf);
1435
2.20k
    mv_merge_refine_pred_flag(&mvf, cu->cb_width, cu->cb_height);
1436
2.20k
    ff_vvc_store_mvf(lc, &mvf);
1437
2.20k
    mvf_to_mi(&mvf, mi);
1438
2.20k
    cu->intra_pred_mode_y   = cu->intra_pred_mode_c = INTRA_PLANAR;
1439
2.20k
    cu->intra_luma_ref_idx  = 0;
1440
2.20k
    cu->intra_mip_flag      = 0;
1441
2.20k
}
1442
1443
// block-based inter prediction data
1444
static void merge_data_block(VVCLocalContext *lc)
1445
54.9k
{
1446
54.9k
    const VVCFrameContext* fc       = lc->fc;
1447
54.9k
    const VVCSPS *sps               = fc->ps.sps;
1448
54.9k
    const H266RawSliceHeader *rsh   = lc->sc->sh.r;
1449
54.9k
    CodingUnit *cu                  = lc->cu;
1450
54.9k
    const int cb_width              = cu->cb_width;
1451
54.9k
    const int cb_height             = cu->cb_height;
1452
54.9k
    const int is_128                = cb_width == 128 || cb_height == 128;
1453
54.9k
    const int ciip_avaiable         = sps->r->sps_ciip_enabled_flag &&
1454
29.6k
        !cu->skip_flag && (cb_width * cb_height >= 64);
1455
54.9k
    const int gpm_avaiable          = sps->r->sps_gpm_enabled_flag && IS_B(rsh) &&
1456
38.3k
        (cb_width >= 8) && (cb_height >=8) &&
1457
31.1k
        (cb_width < 8 * cb_height) && (cb_height < 8 *cb_width);
1458
1459
54.9k
    int regular_merge_flag = 1;
1460
1461
54.9k
    if (!is_128 && (ciip_avaiable || gpm_avaiable))
1462
33.9k
        regular_merge_flag = ff_vvc_regular_merge_flag(lc, cu->skip_flag);
1463
54.9k
    if (regular_merge_flag) {
1464
43.3k
        merge_data_regular(lc);
1465
43.3k
    } else {
1466
11.5k
        cu->ciip_flag = ciip_flag_decode(lc, ciip_avaiable, gpm_avaiable, is_128);
1467
11.5k
        if (cu->ciip_flag)
1468
2.20k
            merge_data_ciip(lc);
1469
9.35k
        else
1470
9.35k
            merge_data_gpm(lc);
1471
11.5k
    }
1472
54.9k
}
1473
1474
static int merge_data_ibc(VVCLocalContext *lc)
1475
115k
{
1476
115k
    const VVCFrameContext* fc = lc->fc;
1477
115k
    const VVCSPS* sps         = fc->ps.sps;
1478
115k
    MotionInfo *mi            = &lc->cu->pu.mi;
1479
115k
    int merge_idx             = 0;
1480
115k
    int ret;
1481
1482
115k
    mi->pred_flag = PF_IBC;
1483
1484
115k
    if (sps->max_num_ibc_merge_cand > 1)
1485
115k
        merge_idx = ff_vvc_merge_idx(lc);
1486
1487
115k
    ret = ff_vvc_luma_mv_merge_ibc(lc, merge_idx, &mi->mv[L0][0]);
1488
115k
    if (ret)
1489
90
        return ret;
1490
115k
    ff_vvc_store_mv(lc, mi);
1491
1492
115k
    return 0;
1493
115k
}
1494
1495
static int hls_merge_data(VVCLocalContext *lc)
1496
174k
{
1497
174k
    const VVCFrameContext *fc   = lc->fc;
1498
174k
    const VVCPH  *ph            = &fc->ps.ph;
1499
174k
    const CodingUnit *cu        = lc->cu;
1500
174k
    PredictionUnit *pu          = &lc->cu->pu;
1501
174k
    int ret;
1502
1503
174k
    pu->merge_gpm_flag = 0;
1504
174k
    pu->mi.num_sb_x = pu->mi.num_sb_y = 1;
1505
174k
    if (cu->pred_mode == MODE_IBC) {
1506
115k
        ret = merge_data_ibc(lc);
1507
115k
        if (ret)
1508
90
            return ret;
1509
115k
    } else {
1510
59.0k
        if (ph->max_num_subblock_merge_cand > 0 && cu->cb_width >= 8 && cu->cb_height >= 8)
1511
22.8k
            pu->merge_subblock_flag = ff_vvc_merge_subblock_flag(lc);
1512
59.0k
        if (pu->merge_subblock_flag)
1513
4.08k
            merge_data_subblock(lc);
1514
54.9k
        else
1515
54.9k
            merge_data_block(lc);
1516
59.0k
    }
1517
174k
    return 0;
1518
174k
}
1519
1520
static void hls_mvd_coding(VVCLocalContext *lc, Mv* mvd)
1521
274k
{
1522
274k
    int32_t mv[2];
1523
1524
824k
    for (int i = 0; i < 2; i++) {
1525
549k
        mv[i] = ff_vvc_abs_mvd_greater0_flag(lc);
1526
549k
    }
1527
1528
824k
    for (int i = 0; i < 2; i++) {
1529
549k
        if (mv[i])
1530
386k
            mv[i] += ff_vvc_abs_mvd_greater1_flag(lc);
1531
549k
    }
1532
1533
824k
    for (int i = 0; i < 2; i++) {
1534
549k
        if (mv[i] > 0) {
1535
386k
            if (mv[i] == 2)
1536
296k
                mv[i] += ff_vvc_abs_mvd_minus2(lc);
1537
386k
            mv[i] = (1 - 2 * ff_vvc_mvd_sign_flag(lc)) * mv[i];
1538
386k
        }
1539
549k
    }
1540
274k
    mvd->x = mv[0];
1541
274k
    mvd->y = mv[1];
1542
274k
}
1543
1544
static int bcw_idx_decode(VVCLocalContext *lc, const MotionInfo *mi, const int cb_width, const int cb_height)
1545
33.5k
{
1546
33.5k
    const VVCFrameContext *fc   = lc->fc;
1547
33.5k
    const VVCSPS *sps           = fc->ps.sps;
1548
33.5k
    const VVCPPS *pps           = fc->ps.pps;
1549
33.5k
    const VVCPH  *ph            = &fc->ps.ph;
1550
33.5k
    const VVCSH *sh             = &lc->sc->sh;
1551
33.5k
    const PredWeightTable *w    = pps->r->pps_wp_info_in_ph_flag ? &ph->pwt : &sh->pwt;
1552
33.5k
    int bcw_idx                 = 0;
1553
1554
33.5k
    if (sps->r->sps_bcw_enabled_flag && mi->pred_flag == PF_BI &&
1555
627
        !w->weight_flag[L0][LUMA][mi->ref_idx[0]] &&
1556
458
        !w->weight_flag[L1][LUMA][mi->ref_idx[1]] &&
1557
458
        !w->weight_flag[L0][CHROMA][mi->ref_idx[0]] &&
1558
369
        !w->weight_flag[L1][CHROMA][mi->ref_idx[1]] &&
1559
344
        cb_width * cb_height >= 256) {
1560
0
        bcw_idx = ff_vvc_bcw_idx(lc, ff_vvc_no_backward_pred_flag(lc));
1561
0
    }
1562
33.5k
    return bcw_idx;
1563
33.5k
}
1564
1565
static int8_t ref_idx_decode(VVCLocalContext *lc, const VVCSH *sh, const int sym_mvd_flag, const int lx)
1566
35.4k
{
1567
35.4k
    const H266RawSliceHeader *rsh   = sh->r;
1568
35.4k
    int ref_idx                     = 0;
1569
1570
35.4k
    if (rsh->num_ref_idx_active[lx] > 1 && !sym_mvd_flag)
1571
1.07k
        ref_idx = ff_vvc_ref_idx_lx(lc, rsh->num_ref_idx_active[lx]);
1572
34.3k
    else if (sym_mvd_flag)
1573
316
        ref_idx = sh->ref_idx_sym[lx];
1574
35.4k
    return ref_idx;
1575
35.4k
}
1576
1577
static int mvds_decode(VVCLocalContext *lc, Mv mvds[2][MAX_CONTROL_POINTS],
1578
    const int num_cp_mv, const int lx)
1579
35.4k
{
1580
35.4k
    const VVCFrameContext *fc   = lc->fc;
1581
35.4k
    const VVCPH *ph             = &fc->ps.ph;
1582
35.4k
    const PredictionUnit *pu    = &lc->cu->pu;
1583
35.4k
    const MotionInfo *mi        = &pu->mi;
1584
35.4k
    int has_no_zero_mvd         = 0;
1585
1586
35.4k
    if (lx == L1 && ph->r->ph_mvd_l1_zero_flag && mi->pred_flag == PF_BI) {
1587
1.06k
        for (int j = 0; j < num_cp_mv; j++)
1588
533
            AV_ZERO64(&mvds[lx][j]);
1589
34.9k
    } else {
1590
34.9k
        Mv *mvd0 = &mvds[lx][0];
1591
34.9k
        if (lx == L1 && pu->sym_mvd_flag) {
1592
158
            mvd0->x = -mvds[L0][0].x;
1593
158
            mvd0->y = -mvds[L0][0].y;
1594
34.7k
        } else {
1595
34.7k
            hls_mvd_coding(lc, mvd0);
1596
34.7k
        }
1597
34.9k
        has_no_zero_mvd |= (mvd0->x || mvd0->y);
1598
34.9k
        for (int j = 1; j < num_cp_mv; j++) {
1599
0
            Mv *mvd = &mvds[lx][j];
1600
0
            hls_mvd_coding(lc, mvd);
1601
0
            mvd->x += mvd0->x;
1602
0
            mvd->y += mvd0->y;
1603
0
            has_no_zero_mvd |= (mvd->x || mvd->y);
1604
0
        }
1605
34.9k
    }
1606
35.4k
    return has_no_zero_mvd;
1607
35.4k
}
1608
1609
static void mvp_add_difference(MotionInfo *mi, const int num_cp_mv,
1610
    const Mv mvds[2][MAX_CONTROL_POINTS], const int amvr_shift)
1611
33.5k
{
1612
100k
    for (int i = 0; i < 2; i++) {
1613
67.0k
        const PredFlag mask = i + PF_L0;
1614
67.0k
        if (mi->pred_flag & mask) {
1615
70.8k
            for (int j = 0; j < num_cp_mv; j++) {
1616
35.4k
                const Mv *mvd = &mvds[i][j];
1617
35.4k
                mi->mv[i][j].x += mvd->x * (1 << amvr_shift);
1618
35.4k
                mi->mv[i][j].y += mvd->y * (1 << amvr_shift);
1619
35.4k
            }
1620
35.4k
        }
1621
67.0k
    }
1622
33.5k
}
1623
1624
static int mvp_data_ibc(VVCLocalContext *lc)
1625
239k
{
1626
239k
    const VVCFrameContext *fc = lc->fc;
1627
239k
    const CodingUnit *cu      = lc->cu;
1628
239k
    const PredictionUnit *pu  = &lc->cu->pu;
1629
239k
    const VVCSPS *sps         = fc->ps.sps;
1630
239k
    MotionInfo *mi            = &lc->cu->pu.mi;
1631
239k
    int mvp_l0_flag           = 0;
1632
239k
    int amvr_shift            = 4;
1633
239k
    Mv *mv                    = &mi->mv[L0][0];
1634
239k
    int ret;
1635
1636
239k
    mi->pred_flag = PF_IBC;
1637
239k
    mi->num_sb_x  = 1;
1638
239k
    mi->num_sb_y  = 1;
1639
1640
239k
    hls_mvd_coding(lc, mv);
1641
239k
    if (sps->max_num_ibc_merge_cand > 1)
1642
238k
        mvp_l0_flag = ff_vvc_mvp_lx_flag(lc);
1643
239k
    if (sps->r->sps_amvr_enabled_flag && (mv->x || mv->y))
1644
169k
        amvr_shift = ff_vvc_amvr_shift(lc, pu->inter_affine_flag, cu->pred_mode, 1);
1645
1646
239k
    ret = ff_vvc_mvp_ibc(lc, mvp_l0_flag, amvr_shift, mv);
1647
239k
    if (ret)
1648
17.0k
        return ret;
1649
222k
    ff_vvc_store_mv(lc, mi);
1650
1651
222k
    return 0;
1652
239k
}
1653
1654
static int mvp_data(VVCLocalContext *lc)
1655
33.5k
{
1656
33.5k
    const VVCFrameContext *fc       = lc->fc;
1657
33.5k
    const CodingUnit *cu            = lc->cu;
1658
33.5k
    PredictionUnit *pu              = &lc->cu->pu;
1659
33.5k
    const VVCSPS *sps               = fc->ps.sps;
1660
33.5k
    const VVCPH *ph                 = &fc->ps.ph;
1661
33.5k
    const VVCSH *sh                 = &lc->sc->sh;
1662
33.5k
    const H266RawSliceHeader *rsh   = sh->r;
1663
33.5k
    MotionInfo *mi                  = &pu->mi;
1664
33.5k
    const int cb_width              = cu->cb_width;
1665
33.5k
    const int cb_height             = cu->cb_height;
1666
1667
33.5k
    int mvp_lx_flag[2] = {0};
1668
33.5k
    int cu_affine_type_flag = 0;
1669
33.5k
    int num_cp_mv;
1670
33.5k
    int amvr_enabled, has_no_zero_mvd = 0, amvr_shift;
1671
33.5k
    Mv mvds[2][MAX_CONTROL_POINTS];
1672
1673
33.5k
    mi->pred_flag = ff_vvc_pred_flag(lc, IS_B(rsh));
1674
33.5k
    if (sps->r->sps_affine_enabled_flag && cb_width >= 16 && cb_height >= 16) {
1675
0
        pu->inter_affine_flag = ff_vvc_inter_affine_flag(lc);
1676
0
        set_cb_tab(lc, fc->tab.iaf, pu->inter_affine_flag);
1677
0
        if (sps->r->sps_6param_affine_enabled_flag && pu->inter_affine_flag)
1678
0
            cu_affine_type_flag = ff_vvc_cu_affine_type_flag(lc);
1679
0
    }
1680
33.5k
    mi->motion_model_idc = pu->inter_affine_flag + cu_affine_type_flag;
1681
33.5k
    num_cp_mv = mi->motion_model_idc + 1;
1682
1683
33.5k
    if (sps->r->sps_smvd_enabled_flag && !ph->r->ph_mvd_l1_zero_flag &&
1684
5.80k
        mi->pred_flag == PF_BI && !pu->inter_affine_flag &&
1685
1.02k
        sh->ref_idx_sym[0] > -1 && sh->ref_idx_sym[1] > -1)
1686
171
        pu->sym_mvd_flag = ff_vvc_sym_mvd_flag(lc);
1687
1688
100k
    for (int i = L0; i <= L1; i++) {
1689
67.0k
        const PredFlag pred_flag = PF_L0 + !i;
1690
67.0k
        if (mi->pred_flag != pred_flag) {
1691
35.4k
            mi->ref_idx[i] = ref_idx_decode(lc, sh, pu->sym_mvd_flag, i);
1692
35.4k
            has_no_zero_mvd |= mvds_decode(lc, mvds, num_cp_mv, i);
1693
35.4k
            mvp_lx_flag[i] = ff_vvc_mvp_lx_flag(lc);
1694
35.4k
        }
1695
67.0k
    }
1696
1697
33.5k
    amvr_enabled = mi->motion_model_idc == MOTION_TRANSLATION ?
1698
33.5k
        sps->r->sps_amvr_enabled_flag : sps->r->sps_affine_amvr_enabled_flag;
1699
33.5k
    amvr_enabled &= has_no_zero_mvd;
1700
1701
33.5k
    amvr_shift = ff_vvc_amvr_shift(lc, pu->inter_affine_flag, cu->pred_mode, amvr_enabled);
1702
1703
33.5k
    mi->hpel_if_idx = amvr_shift == 3;
1704
33.5k
    mi->bcw_idx = bcw_idx_decode(lc, mi, cb_width, cb_height);
1705
1706
33.5k
    if (mi->motion_model_idc)
1707
0
        ff_vvc_affine_mvp(lc, mvp_lx_flag, amvr_shift, mi);
1708
33.5k
    else
1709
33.5k
        ff_vvc_mvp(lc, mvp_lx_flag, amvr_shift, mi);
1710
1711
33.5k
    mvp_add_difference(mi, num_cp_mv, mvds, amvr_shift);
1712
1713
33.5k
    if (mi->motion_model_idc)
1714
0
        ff_vvc_store_sb_mvs(lc, pu);
1715
33.5k
    else
1716
33.5k
        ff_vvc_store_mv(lc, &pu->mi);
1717
1718
33.5k
    return 0;
1719
33.5k
}
1720
1721
// derive bdofFlag from 8.5.6 Decoding process for inter blocks
1722
// derive dmvr from 8.5.1 General decoding process for coding units coded in inter prediction mode
1723
static void derive_dmvr_bdof_flag(const VVCLocalContext *lc, PredictionUnit *pu)
1724
79.0k
{
1725
79.0k
    const VVCFrameContext *fc   = lc->fc;
1726
79.0k
    const VVCPPS *pps           = fc->ps.pps;
1727
79.0k
    const VVCPH *ph             = &fc->ps.ph;
1728
79.0k
    const VVCSH *sh             = &lc->sc->sh;
1729
79.0k
    const int poc               = ph->poc;
1730
79.0k
    const MotionInfo *mi        = &pu->mi;
1731
79.0k
    const int8_t *ref_idx       = mi->ref_idx;
1732
79.0k
    const VVCRefPic *rp0        = &lc->sc->rpl[L0].refs[ref_idx[L0]];
1733
79.0k
    const VVCRefPic *rp1        = &lc->sc->rpl[L1].refs[ref_idx[L1]];
1734
79.0k
    const CodingUnit *cu        = lc->cu;
1735
79.0k
    const PredWeightTable *w    = pps->r->pps_wp_info_in_ph_flag ? &fc->ps.ph.pwt : &sh->pwt;
1736
1737
79.0k
    pu->bdof_flag = 0;
1738
1739
79.0k
    if (mi->pred_flag == PF_BI &&
1740
30.6k
        (poc - rp0->poc == rp1->poc - poc) &&
1741
3.95k
        !rp0->is_lt && !rp1->is_lt &&
1742
3.95k
        !cu->ciip_flag &&
1743
3.37k
        !mi->bcw_idx &&
1744
3.37k
        !w->weight_flag[L0][LUMA][ref_idx[L0]] && !w->weight_flag[L1][LUMA][ref_idx[L1]] &&
1745
2.21k
        !w->weight_flag[L0][CHROMA][ref_idx[L0]] && !w->weight_flag[L1][CHROMA][ref_idx[L1]] &&
1746
2.04k
        cu->cb_width >= 8 && cu->cb_height >= 8 &&
1747
2.04k
        (cu->cb_width * cu->cb_height >= 128) &&
1748
0
        !rp0->is_scaled && !rp1->is_scaled) {
1749
0
        if (!ph->r->ph_bdof_disabled_flag &&
1750
0
            mi->motion_model_idc == MOTION_TRANSLATION &&
1751
0
            !pu->merge_subblock_flag &&
1752
0
            !pu->sym_mvd_flag)
1753
0
            pu->bdof_flag = 1;
1754
0
        if (!ph->r->ph_dmvr_disabled_flag &&
1755
0
            pu->general_merge_flag &&
1756
0
            !pu->mmvd_merge_flag)
1757
0
            pu->dmvr_flag = 1;
1758
0
    }
1759
79.0k
}
1760
1761
// part of 8.5.1 General decoding process for coding units coded in inter prediction mode
1762
static void refine_regular_subblock(const VVCLocalContext *lc)
1763
79.0k
{
1764
79.0k
    const CodingUnit *cu    = lc->cu;
1765
79.0k
    PredictionUnit *pu      = &lc->cu->pu;
1766
1767
79.0k
    derive_dmvr_bdof_flag(lc, pu);
1768
79.0k
    if (pu->dmvr_flag || pu->bdof_flag) {
1769
0
        pu->mi.num_sb_x = (cu->cb_width > 16) ? (cu->cb_width >> 4) : 1;
1770
0
        pu->mi.num_sb_y = (cu->cb_height > 16) ? (cu->cb_height >> 4) : 1;
1771
0
    }
1772
79.0k
}
1773
1774
static void fill_dmvr_info(const VVCLocalContext *lc)
1775
431k
{
1776
431k
    const VVCFrameContext *fc = lc->fc;
1777
431k
    const CodingUnit *cu      = lc->cu;
1778
1779
431k
    if (cu->pred_mode == MODE_IBC || cu->pred_mode == MODE_PLT) {
1780
338k
        ff_vvc_set_intra_mvf(lc, true, cu->pred_mode == MODE_IBC ? PF_IBC : PF_PLT, false);
1781
338k
    } else {
1782
92.5k
        const VVCPPS *pps = fc->ps.pps;
1783
92.5k
        const int w       = cu->cb_width >> MIN_PU_LOG2;
1784
1785
261k
        for (int y = cu->y0 >> MIN_PU_LOG2; y < (cu->y0 + cu->cb_height) >> MIN_PU_LOG2; y++) {
1786
169k
            const int idx = pps->min_pu_width * y + (cu->x0 >> MIN_PU_LOG2);
1787
169k
            const MvField *mvf = fc->tab.mvf + idx;
1788
169k
            MvField *dmvr_mvf  = fc->ref->tab_dmvr_mvf + idx;
1789
1790
169k
            memcpy(dmvr_mvf, mvf, sizeof(MvField) * w);
1791
169k
        }
1792
92.5k
    }
1793
431k
}
1794
1795
static int inter_data(VVCLocalContext *lc)
1796
448k
{
1797
448k
    const CodingUnit *cu    = lc->cu;
1798
448k
    PredictionUnit *pu      = &lc->cu->pu;
1799
448k
    const MotionInfo *mi    = &pu->mi;
1800
448k
    int ret                 = 0;
1801
1802
448k
    pu->general_merge_flag = 1;
1803
448k
    if (!cu->skip_flag)
1804
392k
        pu->general_merge_flag = ff_vvc_general_merge_flag(lc);
1805
1806
448k
    if (pu->general_merge_flag) {
1807
174k
        ret = hls_merge_data(lc);
1808
273k
    } else if (cu->pred_mode == MODE_IBC) {
1809
239k
        ret = mvp_data_ibc(lc);
1810
239k
    } else {
1811
33.5k
        ret = mvp_data(lc);
1812
33.5k
    }
1813
1814
448k
    if (ret)
1815
17.1k
        return ret;
1816
1817
431k
    if (cu->pred_mode == MODE_IBC) {
1818
338k
        ff_vvc_update_hmvp(lc, mi);
1819
338k
    } else if (!pu->merge_gpm_flag && !pu->inter_affine_flag && !pu->merge_subblock_flag) {
1820
79.0k
        refine_regular_subblock(lc);
1821
79.0k
        ff_vvc_update_hmvp(lc, mi);
1822
79.0k
    }
1823
1824
431k
    if (!pu->dmvr_flag)
1825
431k
        fill_dmvr_info(lc);
1826
431k
    return ret;
1827
448k
}
1828
1829
static TransformUnit* palette_add_tu(VVCLocalContext *lc, const int start, const int end, const VVCTreeType tree_type)
1830
77.6k
{
1831
77.6k
    CodingUnit   *cu  = lc->cu;
1832
77.6k
    const VVCSPS *sps = lc->fc->ps.sps;
1833
77.6k
    TransformUnit *tu = add_tu(lc->fc, cu, cu->x0, cu->y0, cu->cb_width, cu->cb_height);
1834
1835
77.6k
    if (!tu)
1836
0
        return NULL;
1837
1838
237k
    for (int c = start; c < end; c++) {
1839
160k
        const int w = tu->width >> sps->hshift[c];
1840
160k
        const int h = tu->height >> sps->vshift[c];
1841
160k
        TransformBlock *tb = add_tb(tu, lc, tu->x0, tu->y0, w, h, c);
1842
160k
        if (c != CR)
1843
92.4k
            set_tb_size(lc->fc, tb);
1844
160k
    }
1845
1846
310k
    for (int i = 0; i < FF_ARRAY_ELEMS(cu->plt); i++)
1847
232k
        cu->plt[i].size = 0;
1848
1849
77.6k
    return tu;
1850
77.6k
}
1851
1852
static int palette_predicted(VVCLocalContext *lc, const bool local_dual_tree, int start, int end,
1853
    bool *predictor_reused, const int predictor_size, const int max_entries)
1854
77.6k
{
1855
77.6k
    CodingUnit  *cu  = lc->cu;
1856
77.6k
    int nb_predicted = 0;
1857
1858
77.6k
    if (local_dual_tree) {
1859
1.09k
        start = LUMA;
1860
1.09k
        end = VVC_MAX_SAMPLE_ARRAYS;
1861
1.09k
    }
1862
1863
78.8k
    for (int i = 0; i < predictor_size && nb_predicted < max_entries; i++) {
1864
1.83k
        const int run = ff_vvc_palette_predictor_run(lc, predictor_size - i);
1865
1.83k
        if (run < 0)
1866
173
            return run;
1867
1868
1.66k
        if (run == 1)
1869
465
            break;
1870
1871
1.20k
        if (run > 1)
1872
198
            i += run - 1;
1873
1874
1.20k
        predictor_reused[i] = true;
1875
3.67k
        for (int c = start; c < end; c++)
1876
2.47k
            cu->plt[c].entries[nb_predicted] = lc->ep->pp[c].entries[i];
1877
1.20k
        nb_predicted++;
1878
1.20k
    }
1879
1880
239k
    for (int c = start; c < end; c++)
1881
161k
        cu->plt[c].size = nb_predicted;
1882
1883
77.4k
    return 0;
1884
77.6k
}
1885
1886
static int palette_signaled(VVCLocalContext *lc, const bool local_dual_tree,
1887
    const int start, const int end, const int max_entries)
1888
77.4k
{
1889
77.4k
    const VVCSPS *sps         = lc->fc->ps.sps;
1890
77.4k
    CodingUnit  *cu           = lc->cu;
1891
77.4k
    const int nb_predicted    = cu->plt[start].size;
1892
77.4k
    const int nb_signaled     = nb_predicted < max_entries ? ff_vvc_num_signalled_palette_entries(lc, max_entries - nb_predicted) : 0;
1893
77.4k
    const int size            = nb_predicted + nb_signaled;
1894
77.4k
    const bool dual_tree_luma = local_dual_tree && cu->tree_type == DUAL_TREE_LUMA;
1895
1896
77.4k
    if (nb_signaled < 0)
1897
429
        return AVERROR_INVALIDDATA;
1898
1899
236k
    for (int c = start; c < end; c++) {
1900
159k
        Palette *plt = cu->plt + c;
1901
763k
        for (int i = nb_predicted; i < size; i++) {
1902
604k
            plt->entries[i] = ff_vvc_new_palette_entries(lc, sps->bit_depth);
1903
604k
            if (dual_tree_luma) {
1904
373
                plt[CB].entries[i] = 1 << (sps->bit_depth - 1);
1905
373
                plt[CR].entries[i] = 1 << (sps->bit_depth - 1);
1906
373
            }
1907
604k
        }
1908
159k
        plt->size = size;
1909
159k
    }
1910
1911
77.0k
    return 0;
1912
77.4k
}
1913
1914
static void palette_update_predictor(VVCLocalContext *lc, const bool local_dual_tree, int start, int end,
1915
    bool *predictor_reused, const int predictor_size)
1916
77.0k
{
1917
77.0k
    CodingUnit  *cu         = lc->cu;
1918
77.0k
    const int max_predictor = VVC_MAX_NUM_PALETTE_PREDICTOR_SIZE >> (cu->tree_type != SINGLE_TREE && !local_dual_tree);
1919
1920
77.0k
    if (local_dual_tree) {
1921
855
        start = LUMA;
1922
855
        end = VVC_MAX_SAMPLE_ARRAYS;
1923
855
    }
1924
1925
237k
    for (int c = start; c < end; c++) {
1926
160k
        Palette *pp  = lc->ep->pp + c;
1927
160k
        Palette *plt = cu->plt + c;
1928
160k
        int i = cu->plt[start].size;;
1929
1930
        // copy unused predictors to the end of plt
1931
165k
        for (int j = 0; j < predictor_size && i < max_predictor; j++) {
1932
4.74k
            if (!predictor_reused[j]) {
1933
2.51k
                plt->entries[i] = pp->entries[j];
1934
2.51k
                i++;
1935
2.51k
            }
1936
4.74k
        }
1937
1938
160k
        memcpy(pp->entries, plt->entries, i * sizeof(pp->entries[0]));
1939
160k
        pp->size = i;
1940
160k
    }
1941
77.0k
}
1942
1943
static int palette_qp(VVCLocalContext *lc, VVCTreeType tree_type, const bool escape_present)
1944
77.0k
{
1945
77.0k
    const VVCFrameContext *fc     = lc->fc;
1946
77.0k
    const VVCPPS *pps             = fc->ps.pps;
1947
77.0k
    const H266RawSliceHeader *rsh = lc->sc->sh.r;
1948
77.0k
    const CodingUnit *cu          = lc->cu;
1949
77.0k
    int ret;
1950
1951
77.0k
    if (tree_type != DUAL_TREE_CHROMA) {
1952
24.1k
        const bool has_qp_delta = escape_present &&
1953
10.4k
            pps->r->pps_cu_qp_delta_enabled_flag && !lc->parse.is_cu_qp_delta_coded;
1954
24.1k
        ret = set_qp_y(lc, cu->x0, cu->y0, has_qp_delta);
1955
24.1k
        if (ret < 0)
1956
4
            return ret;
1957
24.1k
    }
1958
1959
76.9k
    if (tree_type != DUAL_TREE_LUMA) {
1960
68.2k
        if (rsh->sh_cu_chroma_qp_offset_enabled_flag && !lc->parse.is_cu_chroma_qp_offset_coded)
1961
297
            chroma_qp_offset_decode(lc, 0, 1);
1962
68.2k
        set_qp_c(lc);
1963
68.2k
    }
1964
1965
76.9k
    return 0;
1966
77.0k
}
1967
1968
#define PALETTE_SET_PIXEL(xc, yc, pix)                              \
1969
8.58M
    do {                                                            \
1970
8.58M
        const int off = ((xc) >> hs) + ((yc) >> vs) * tb->tb_width; \
1971
8.58M
        if (sps->bit_depth == 8)                                    \
1972
8.58M
            u8[off] = pix;                                          \
1973
8.58M
        else                                                        \
1974
8.58M
            u16[off] = pix;                                         \
1975
8.58M
    } while (0)
1976
1977
18.4M
#define PALETTE_INDEX(x, y) index[(y) * width + (x)]
1978
1979
// 6.5.3 Horizontal and vertical traverse scan order array initialization process
1980
// The hTravScan and vTravScan tables require approximately 576 KB of memory.
1981
// To save space, we use a macro to achieve the same functionality.
1982
22.6M
#define TRAV_COL(p, wlog, mask) ((p & mask) ^ (-((p >> wlog) & 1) & mask))
1983
22.6M
#define TRAV_ROW(p, hlog) (p >> hlog)
1984
45.2M
#define TRAV(trans, p, wlog, hlog, mask)  (trans ? TRAV_ROW((p), hlog) : TRAV_COL((p), wlog, mask))
1985
22.6M
#define TRAV_X(pos) TRAV(transpose, pos, wlog2, hlog2, wmask)
1986
22.6M
#define TRAV_Y(pos) TRAV(!transpose, pos, hlog2, wlog2, hmask)
1987
1988
static int palette_subblock_data(VVCLocalContext *lc,
1989
    const int max_index, const int subset_id, const bool transpose,
1990
    uint8_t *run_type, uint8_t *index, int *prev_run_pos, bool *adjust)
1991
292k
{
1992
292k
    const CodingUnit *cu = lc->cu;
1993
292k
    TransformUnit *tu    = cu->tus.head;
1994
292k
    const VVCSPS *sps    = lc->fc->ps.sps;
1995
292k
    const int width      = tu->tbs[0].tb_width;
1996
292k
    const int height     = tu->tbs[0].tb_height;
1997
292k
    const int min_pos    = subset_id << 4;
1998
292k
    const int max_pos    = FFMIN(min_pos + 16, width * height);
1999
292k
    const int wmask      = width  - 1;
2000
292k
    const int hmask      = height - 1;
2001
292k
    const int wlog2      = av_log2(width);
2002
292k
    const int hlog2      = av_log2(height);
2003
292k
    const int start_idx  = tu->tbs[0].c_idx;
2004
292k
    const uint8_t esc    = cu->plt[tu->tbs[0].c_idx].size;
2005
292k
    uint8_t run_copy[16] = { 0 };
2006
2007
4.97M
    for (int i = min_pos; i < max_pos; i++) {
2008
4.68M
        const int xc = TRAV_X(i);
2009
4.68M
        const int yc = TRAV_Y(i);
2010
2011
4.68M
        if (i > 0 && max_index > 0)
2012
4.06M
            run_copy[i - min_pos] = ff_vvc_run_copy_flag(lc, run_type[i - 1], *prev_run_pos, i);
2013
2014
4.68M
        run_type[i] = 0;
2015
4.68M
        if (max_index > 0 && !run_copy[i - min_pos]) {
2016
828k
            if (((!transpose && yc > 0) || (transpose && xc > 0))
2017
517k
                && i > 0 && !run_type[i - 1]) {
2018
389k
                run_type[i] = ff_vvc_copy_above_palette_indices_flag(lc);
2019
389k
            }
2020
828k
            *prev_run_pos = i;
2021
3.85M
        } else if (i > 0) {
2022
3.84M
            run_type[i] = run_type[i - 1];
2023
3.84M
        }
2024
4.68M
    }
2025
2026
4.97M
    for (int i = min_pos; i < max_pos; i++) {
2027
4.68M
        const int xc = TRAV_X(i);
2028
4.68M
        const int yc = TRAV_Y(i);
2029
4.68M
        const int prev_xc = i > 0 ? TRAV_X(i - 1) : 0;
2030
4.68M
        const int prev_yc = i > 0 ? TRAV_Y(i - 1) : 0;
2031
2032
4.68M
        int idx = 0;
2033
4.68M
        if (max_index > 0 && !run_copy[i - min_pos] && !run_type[i]) {
2034
693k
            if (max_index - *adjust > 0)
2035
589k
                idx = ff_vvc_palette_idx_idc(lc, max_index, *adjust);
2036
693k
            if (i > 0) {
2037
628k
                const int ref_idx = !run_type[i - 1] ?
2038
499k
                    PALETTE_INDEX(prev_xc, prev_yc) : PALETTE_INDEX(xc - transpose, yc - !transpose);
2039
628k
                idx += (idx >= ref_idx);
2040
628k
            }
2041
693k
            *adjust = true;
2042
3.98M
        } else {
2043
3.98M
            idx = PALETTE_INDEX(prev_xc, prev_yc);
2044
3.98M
        }
2045
2046
4.68M
        if (!run_type[i])
2047
4.16M
            PALETTE_INDEX(xc, yc) = idx;
2048
521k
        else
2049
521k
            PALETTE_INDEX(xc, yc) = PALETTE_INDEX(xc - transpose, yc - !transpose);
2050
4.68M
    }
2051
2052
827k
    for (int c = 0; c < tu->nb_tbs; c++) {
2053
544k
        TransformBlock *tb = &tu->tbs[c];
2054
544k
        const int c_idx    = tb->c_idx;
2055
544k
        const Palette *plt = &cu->plt[c_idx];
2056
544k
        const int scale    = ff_vvc_palette_derive_scale(lc, tu, tb);
2057
544k
        const int hs       = sps->hshift[c_idx] - sps->hshift[start_idx];
2058
544k
        const int vs       = sps->vshift[c_idx] - sps->vshift[start_idx];
2059
544k
        uint8_t *u8        = (uint8_t *)tb->coeffs;
2060
544k
        uint16_t *u16      = (uint16_t *)tb->coeffs;
2061
2062
9.17M
        for (int i = min_pos; i < max_pos; i++) {
2063
8.63M
            const int xc = TRAV_X(i);
2064
8.63M
            const int yc = TRAV_Y(i);
2065
8.63M
            if (!(xc & hs) && !(yc & vs)) {
2066
8.59M
                const int v = PALETTE_INDEX(xc, yc);
2067
8.59M
                if (v == esc) {
2068
906k
                    const int coeff = ff_vvc_palette_escape_val(lc, (1 << sps->bit_depth) - 1);
2069
906k
                    if (coeff < 0)
2070
9.79k
                        return AVERROR_INVALIDDATA;
2071
896k
                    const int pixel = av_clip_intp2(RSHIFT(coeff * scale, 6), sps->bit_depth);
2072
896k
                    PALETTE_SET_PIXEL(xc, yc, pixel);
2073
7.68M
                } else {
2074
7.68M
                    PALETTE_SET_PIXEL(xc, yc, plt->entries[v]);
2075
7.68M
                }
2076
8.59M
            }
2077
8.63M
        }
2078
544k
    }
2079
2080
282k
    return 0;
2081
292k
}
2082
2083
static int hls_palette_coding(VVCLocalContext *lc, const VVCTreeType tree_type)
2084
77.6k
{
2085
77.6k
    const VVCFrameContext *fc     = lc->fc;
2086
77.6k
    const VVCSPS *sps             = fc->ps.sps;
2087
77.6k
    const H266RawSliceHeader *rsh = lc->sc->sh.r;
2088
77.6k
    CodingUnit *cu                = lc->cu;
2089
77.6k
    Palette *pp                   = lc->ep->pp;
2090
77.6k
    const int max_entries         = tree_type == SINGLE_TREE ? 31 : 15;
2091
77.6k
    const bool local_dual_tree    = tree_type != SINGLE_TREE &&
2092
62.0k
                                        (!IS_I(rsh) || (IS_I(rsh) && !sps->r->sps_qtbtt_dual_tree_intra_flag));
2093
77.6k
    bool escape_present           = false;
2094
77.6k
    bool transpose                = false;
2095
77.6k
    bool adjust                   = false;
2096
77.6k
    int max_index                 = 0;
2097
77.6k
    int prev_run_pos              = 0;
2098
2099
77.6k
    int predictor_size, start, end, ret;
2100
77.6k
    bool reused[VVC_MAX_NUM_PALETTE_PREDICTOR_SIZE];
2101
77.6k
    uint8_t run_type[MAX_PALETTE_CU_SIZE * MAX_PALETTE_CU_SIZE];
2102
77.6k
    uint8_t index[MAX_PALETTE_CU_SIZE * MAX_PALETTE_CU_SIZE];
2103
2104
77.6k
    TransformUnit *tu;
2105
2106
77.6k
    ff_vvc_channel_range(&start, &end, tree_type, sps->r->sps_chroma_format_idc);
2107
2108
77.6k
    tu = palette_add_tu(lc, start, end, tree_type);
2109
77.6k
    if (!tu)
2110
0
        return AVERROR(ENOMEM);
2111
2112
77.6k
    predictor_size = pp[start].size;
2113
77.6k
    memset(reused, 0, sizeof(reused[0]) * predictor_size);
2114
2115
77.6k
    ret = palette_predicted(lc, local_dual_tree, start, end, reused, predictor_size, max_entries);
2116
77.6k
    if (ret < 0)
2117
173
        return ret;
2118
2119
77.4k
    ret = palette_signaled(lc, local_dual_tree, start, end, max_entries);
2120
77.4k
    if (ret < 0)
2121
429
        return ret;
2122
2123
77.0k
    palette_update_predictor(lc, local_dual_tree, start, end, reused, predictor_size);
2124
2125
77.0k
    if (cu->plt[start].size > 0)
2126
65.9k
        escape_present = ff_vvc_palette_escape_val_present_flag(lc);
2127
2128
77.0k
    max_index = cu->plt[start].size - 1 + escape_present;
2129
77.0k
    if (max_index > 0) {
2130
64.8k
        adjust = false;
2131
64.8k
        transpose = ff_vvc_palette_transpose_flag(lc);
2132
64.8k
    }
2133
2134
77.0k
    ret = palette_qp(lc, tree_type, escape_present);
2135
77.0k
    if (ret < 0)
2136
4
        return ret;
2137
2138
76.9k
    index[0] = 0;
2139
359k
    for (int i = 0; i <= (tu->tbs[0].tb_width * tu->tbs[0].tb_height - 1) >> 4; i++) {
2140
292k
        ret = palette_subblock_data(lc, max_index, i, transpose,
2141
292k
            run_type, index, &prev_run_pos, &adjust);
2142
292k
        if (ret < 0)
2143
9.79k
            return ret;
2144
292k
    }
2145
2146
67.2k
    return 0;
2147
76.9k
}
2148
2149
static int intra_data(VVCLocalContext *lc)
2150
8.97M
{
2151
8.97M
    const VVCSPS *sps              = lc->fc->ps.sps;
2152
8.97M
    const CodingUnit *cu           = lc->cu;
2153
8.97M
    const VVCTreeType tree_type    = cu->tree_type;
2154
8.97M
    const bool  pred_mode_plt_flag = cu->pred_mode == MODE_PLT;
2155
8.97M
    int ret                        = 0;
2156
2157
8.97M
    if (tree_type == SINGLE_TREE || tree_type == DUAL_TREE_LUMA) {
2158
5.97M
        if (pred_mode_plt_flag) {
2159
24.6k
            if ((ret = hls_palette_coding(lc, tree_type)) < 0)
2160
9.90k
                return ret;
2161
14.7k
            ff_vvc_set_intra_mvf(lc, false, PF_PLT, false);
2162
5.95M
        } else {
2163
5.95M
            intra_luma_pred_modes(lc);
2164
5.95M
            ff_vvc_set_intra_mvf(lc, false, PF_INTRA, cu->ciip_flag);
2165
5.95M
        }
2166
5.97M
    }
2167
8.96M
    if ((tree_type == SINGLE_TREE || tree_type == DUAL_TREE_CHROMA) && sps->r->sps_chroma_format_idc) {
2168
3.77M
        if (pred_mode_plt_flag && tree_type == DUAL_TREE_CHROMA) {
2169
52.9k
            if ((ret = hls_palette_coding(lc, tree_type)) < 0)
2170
495
                return ret;
2171
3.71M
        } else if (!pred_mode_plt_flag) {
2172
3.70M
            intra_chroma_pred_modes(lc);
2173
3.70M
        }
2174
3.77M
    }
2175
2176
8.96M
    return ret;
2177
8.96M
}
2178
2179
static int hls_coding_unit(VVCLocalContext *lc, int x0, int y0, int cb_width, int cb_height,
2180
    int cqt_depth, const VVCTreeType tree_type, VVCModeType mode_type)
2181
9.42M
{
2182
9.42M
    const VVCFrameContext *fc     = lc->fc;
2183
9.42M
    const VVCSPS *sps             = fc->ps.sps;
2184
9.42M
    const H266RawSliceHeader *rsh = lc->sc->sh.r;
2185
9.42M
    const int is_128              = cb_width > 64 || cb_height > 64;
2186
9.42M
    int ret                       = 0;
2187
2188
9.42M
    CodingUnit *cu = add_cu(lc, x0, y0, cb_width, cb_height, cqt_depth, tree_type);
2189
2190
9.42M
    if (!cu)
2191
0
        return AVERROR(ENOMEM);
2192
2193
9.42M
    ff_vvc_set_neighbour_available(lc, cu->x0, cu->y0, cu->cb_width, cu->cb_height);
2194
2195
9.42M
    if (IS_I(rsh) && is_128)
2196
0
        mode_type = MODE_TYPE_INTRA;
2197
9.42M
    cu->pred_mode = pred_mode_decode(lc, tree_type, mode_type);
2198
2199
9.42M
    if (cu->pred_mode == MODE_INTRA && sps->r->sps_act_enabled_flag && tree_type == SINGLE_TREE)
2200
313k
        cu->act_enabled_flag = ff_vvc_cu_act_enabled_flag(lc);
2201
2202
9.42M
    if (cu->pred_mode == MODE_INTRA || cu->pred_mode == MODE_PLT)
2203
8.97M
        ret = intra_data(lc);
2204
448k
    else if (tree_type != DUAL_TREE_CHROMA) /* MODE_INTER or MODE_IBC */
2205
448k
        ret = inter_data(lc);
2206
2207
9.42M
    if (ret < 0)
2208
27.5k
        return ret;
2209
2210
9.39M
    if (cu->pred_mode != MODE_INTRA && cu->pred_mode != MODE_PLT && !lc->cu->pu.general_merge_flag)
2211
256k
        cu->coded_flag = ff_vvc_cu_coded_flag(lc);
2212
9.14M
    else
2213
9.14M
        cu->coded_flag = !(cu->skip_flag || cu->pred_mode == MODE_PLT);
2214
2215
9.39M
    if (cu->coded_flag) {
2216
9.18M
        sbt_info(lc, sps);
2217
9.18M
        if (sps->r->sps_act_enabled_flag && cu->pred_mode != MODE_INTRA && tree_type == SINGLE_TREE)
2218
6.04k
            cu->act_enabled_flag = ff_vvc_cu_act_enabled_flag(lc);
2219
9.18M
        lc->parse.lfnst_dc_only = 1;
2220
9.18M
        lc->parse.lfnst_zero_out_sig_coeff_flag = 1;
2221
9.18M
        lc->parse.mts_dc_only = 1;
2222
9.18M
        lc->parse.mts_zero_out_sig_coeff_flag = 1;
2223
9.18M
        ret = hls_transform_tree(lc, x0, y0, cb_width, cb_height, cu->ch_type);
2224
9.18M
        if (ret < 0)
2225
2.25k
            return ret;
2226
9.17M
        cu->lfnst_idx = lfnst_idx_decode(lc);
2227
9.17M
        cu->mts_idx = mts_idx_decode(lc);
2228
9.17M
        set_qp_c(lc);
2229
9.17M
    } else if (cu->pred_mode != MODE_PLT) {
2230
149k
        ret = skipped_transform_tree_unit(lc);
2231
149k
        if (ret < 0)
2232
0
            return ret;
2233
149k
    }
2234
9.39M
    set_cu_tabs(lc, cu);
2235
2236
9.39M
    return 0;
2237
9.39M
}
2238
2239
static int derive_mode_type_condition(const VVCLocalContext *lc,
2240
    const VVCSplitMode split, const int cb_width, const int cb_height, const VVCModeType mode_type_curr)
2241
10.3M
{
2242
10.3M
    const H266RawSliceHeader *rsh   = lc->sc->sh.r;
2243
10.3M
    const VVCSPS *sps               = lc->fc->ps.sps;
2244
10.3M
    const int area                  = cb_width * cb_height;
2245
2246
10.3M
    if ((IS_I(rsh) && sps->r->sps_qtbtt_dual_tree_intra_flag) ||
2247
3.65M
        mode_type_curr != MODE_TYPE_ALL || !sps->r->sps_chroma_format_idc ||
2248
3.50M
        sps->r->sps_chroma_format_idc == CHROMA_FORMAT_444)
2249
8.53M
        return 0;
2250
1.84M
    if ((area == 64 && (split == SPLIT_QT || split == SPLIT_TT_HOR || split == SPLIT_TT_VER)) ||
2251
1.63M
        (area == 32 &&  (split == SPLIT_BT_HOR || split == SPLIT_BT_VER)))
2252
208k
        return 1;
2253
1.63M
    if ((area == 64 && (split == SPLIT_BT_HOR || split == SPLIT_BT_VER) && sps->r->sps_chroma_format_idc == CHROMA_FORMAT_420) ||
2254
1.53M
        (area == 128 && (split == SPLIT_TT_HOR || split == SPLIT_TT_VER) && sps->r->sps_chroma_format_idc == CHROMA_FORMAT_420) ||
2255
1.53M
        (cb_width == 8 && split == SPLIT_BT_VER) || (cb_width == 16 && split == SPLIT_TT_VER))
2256
94.4k
        return 1 + !IS_I(rsh);
2257
2258
1.53M
    return 0;
2259
1.63M
}
2260
2261
static VVCModeType mode_type_decode(VVCLocalContext *lc, const int x0, const int y0,
2262
    const int cb_width, const int cb_height, const VVCSplitMode split, const int ch_type,
2263
    const VVCModeType mode_type_curr)
2264
10.3M
{
2265
10.3M
    VVCModeType mode_type;
2266
10.3M
    const int mode_type_condition = derive_mode_type_condition(lc, split, cb_width, cb_height, mode_type_curr);
2267
2268
10.3M
    if (mode_type_condition == 1)
2269
289k
        mode_type = MODE_TYPE_INTRA;
2270
10.0M
    else if (mode_type_condition == 2) {
2271
13.9k
        mode_type = ff_vvc_non_inter_flag(lc, x0, y0, ch_type) ? MODE_TYPE_INTRA : MODE_TYPE_INTER;
2272
10.0M
    } else {
2273
10.0M
        mode_type = mode_type_curr;
2274
10.0M
    }
2275
2276
10.3M
    return mode_type;
2277
10.3M
}
2278
2279
static int hls_coding_tree(VVCLocalContext *lc,
2280
    int x0, int y0, int cb_width, int cb_height, int qg_on_y, int qg_on_c,
2281
    int cb_sub_div, int cqt_depth, int mtt_depth, int depth_offset, int part_idx,
2282
    VVCSplitMode last_split_mode, VVCTreeType tree_type_curr, VVCModeType mode_type_curr);
2283
2284
static int coding_tree_btv(VVCLocalContext *lc,
2285
    int x0, int y0, int cb_width, int cb_height, int qg_on_y, int qg_on_c,
2286
    int cb_sub_div, int cqt_depth, int mtt_depth, int depth_offset,
2287
    VVCTreeType tree_type, VVCModeType mode_type)
2288
1.19M
{
2289
1.89M
#define CODING_TREE(x, idx) do { \
2290
1.89M
    ret = hls_coding_tree(lc, x, y0, cb_width / 2, cb_height, \
2291
1.89M
        qg_on_y, qg_on_c, cb_sub_div + 1, cqt_depth, mtt_depth + 1, \
2292
1.89M
        depth_offset, idx, SPLIT_BT_VER, tree_type, mode_type); \
2293
1.89M
    if (ret < 0) \
2294
1.89M
        return ret; \
2295
1.89M
} while (0);
2296
2297
1.19M
    const VVCPPS *pps = lc->fc->ps.pps;
2298
1.19M
    const int x1 = x0 + cb_width / 2;
2299
1.19M
    int ret = 0;
2300
2301
1.19M
    depth_offset += (x0 + cb_width > pps->width) ? 1 : 0;
2302
1.19M
    CODING_TREE(x0, 0);
2303
1.18M
    if (x1 < pps->width)
2304
1.17M
        CODING_TREE(x1, 1);
2305
2306
1.17M
    return 0;
2307
2308
1.18M
#undef CODING_TREE
2309
1.18M
}
2310
2311
static int coding_tree_bth(VVCLocalContext *lc,
2312
    int x0, int y0, int cb_width, int cb_height, int qg_on_y, int qg_on_c,
2313
    int cb_sub_div, int cqt_depth, int mtt_depth, int depth_offset,
2314
    VVCTreeType tree_type, VVCModeType mode_type)
2315
1.90M
{
2316
3.22M
#define CODING_TREE(y, idx) do { \
2317
3.22M
        ret = hls_coding_tree(lc, x0, y, cb_width , cb_height / 2, \
2318
3.22M
            qg_on_y, qg_on_c, cb_sub_div + 1, cqt_depth, mtt_depth + 1, \
2319
3.22M
            depth_offset, idx, SPLIT_BT_HOR, tree_type, mode_type); \
2320
3.22M
        if (ret < 0) \
2321
3.22M
            return ret; \
2322
3.22M
    } while (0);
2323
2324
1.90M
    const VVCPPS *pps = lc->fc->ps.pps;
2325
1.90M
    const int y1 = y0 + (cb_height / 2);
2326
1.90M
    int ret = 0;
2327
2328
1.90M
    depth_offset += (y0 + cb_height > pps->height) ? 1 : 0;
2329
1.90M
    CODING_TREE(y0, 0);
2330
1.89M
    if (y1 < pps->height)
2331
1.89M
        CODING_TREE(y1, 1);
2332
2333
1.89M
    return 0;
2334
2335
1.89M
#undef CODING_TREE
2336
1.89M
}
2337
2338
static int coding_tree_ttv(VVCLocalContext *lc,
2339
    int x0, int y0, int cb_width, int cb_height, int qg_on_y, int qg_on_c,
2340
    int cb_sub_div, int cqt_depth, int mtt_depth, int depth_offset,
2341
    VVCTreeType tree_type, VVCModeType mode_type)
2342
167k
{
2343
502k
#define CODING_TREE(x, w, sub_div, idx) do { \
2344
502k
        ret = hls_coding_tree(lc, x, y0, w, cb_height, \
2345
502k
            qg_on_y, qg_on_c, sub_div, cqt_depth, mtt_depth + 1, \
2346
502k
            depth_offset, idx, SPLIT_TT_VER, tree_type, mode_type); \
2347
502k
        if (ret < 0) \
2348
502k
            return ret; \
2349
502k
    } while (0);
2350
2351
167k
    const VVCSH *sh = &lc->sc->sh;
2352
167k
    const int x1    = x0 + cb_width / 4;
2353
167k
    const int x2    = x0 + cb_width * 3 / 4;
2354
167k
    int ret;
2355
2356
167k
    qg_on_y = qg_on_y && (cb_sub_div + 2 <= sh->cu_qp_delta_subdiv);
2357
167k
    qg_on_c = qg_on_c && (cb_sub_div + 2 <= sh->cu_chroma_qp_offset_subdiv);
2358
2359
167k
    CODING_TREE(x0, cb_width / 4, cb_sub_div + 2, 0);
2360
167k
    CODING_TREE(x1, cb_width / 2, cb_sub_div + 1, 1);
2361
167k
    CODING_TREE(x2, cb_width / 4, cb_sub_div + 2, 2);
2362
2363
167k
    return 0;
2364
2365
167k
#undef CODING_TREE
2366
167k
}
2367
2368
static int coding_tree_tth(VVCLocalContext *lc,
2369
    int x0, int y0, int cb_width, int cb_height, int qg_on_y, int qg_on_c,
2370
    int cb_sub_div, int cqt_depth, int mtt_depth, int depth_offset,
2371
    VVCTreeType tree_type, VVCModeType mode_type)
2372
180k
{
2373
541k
#define CODING_TREE(y, h, sub_div, idx) do { \
2374
541k
        ret = hls_coding_tree(lc, x0, y, cb_width, h, \
2375
541k
            qg_on_y, qg_on_c, sub_div, cqt_depth, mtt_depth + 1, \
2376
541k
            depth_offset, idx, SPLIT_TT_HOR, tree_type, mode_type); \
2377
541k
        if (ret < 0) \
2378
541k
            return ret; \
2379
541k
    } while (0);
2380
2381
180k
    const VVCSH *sh = &lc->sc->sh;
2382
180k
    const int y1    = y0 + (cb_height / 4);
2383
180k
    const int y2    = y0 + (3 * cb_height / 4);
2384
180k
    int ret;
2385
2386
180k
    qg_on_y = qg_on_y && (cb_sub_div + 2 <= sh->cu_qp_delta_subdiv);
2387
180k
    qg_on_c = qg_on_c && (cb_sub_div + 2 <= sh->cu_chroma_qp_offset_subdiv);
2388
2389
180k
    CODING_TREE(y0, cb_height / 4, cb_sub_div + 2, 0);
2390
180k
    CODING_TREE(y1, cb_height / 2, cb_sub_div + 1, 1);
2391
180k
    CODING_TREE(y2, cb_height / 4, cb_sub_div + 2, 2);
2392
2393
180k
    return 0;
2394
2395
180k
#undef CODING_TREE
2396
180k
}
2397
2398
static int coding_tree_qt(VVCLocalContext *lc,
2399
    int x0, int y0, int cb_width, int cb_height, int qg_on_y, int qg_on_c,
2400
    int cb_sub_div, int cqt_depth, int mtt_depth, int depth_offset,
2401
    VVCTreeType tree_type, VVCModeType mode_type)
2402
6.92M
{
2403
10.4M
#define CODING_TREE(x, y, idx) do { \
2404
10.4M
        ret = hls_coding_tree(lc, x, y, cb_width / 2, cb_height / 2, \
2405
10.4M
            qg_on_y, qg_on_c, cb_sub_div + 2, cqt_depth + 1, 0, 0, \
2406
10.4M
            idx, SPLIT_QT, tree_type, mode_type); \
2407
10.4M
        if (ret < 0) \
2408
10.4M
            return ret; \
2409
10.4M
    } while (0);
2410
2411
6.92M
    const VVCPPS *pps = lc->fc->ps.pps;
2412
6.92M
    const int x1 = x0 + cb_width / 2;
2413
6.92M
    const int y1 = y0 + cb_height / 2;
2414
6.92M
    int ret = 0;
2415
2416
6.92M
    CODING_TREE(x0, y0, 0);
2417
6.84M
    if (x1 < pps->width)
2418
6.83M
        CODING_TREE(x1, y0, 1);
2419
6.83M
    if (y1 < pps->height)
2420
6.83M
        CODING_TREE(x0, y1, 2);
2421
6.83M
    if (x1 < pps->width &&
2422
1.17M
        y1 < pps->height)
2423
6.83M
        CODING_TREE(x1, y1, 3);
2424
2425
6.83M
    return 0;
2426
2427
6.83M
#undef CODING_TREE
2428
6.83M
}
2429
2430
typedef int (*coding_tree_fn)(VVCLocalContext *lc,
2431
    int x0, int y0, int cb_width, int cb_height, int qg_on_y, int qg_on_c,
2432
    int cb_sub_div, int cqt_depth, int mtt_depth, int depth_offset,
2433
    VVCTreeType tree_type, VVCModeType mode_type);
2434
2435
const static coding_tree_fn coding_tree[] = {
2436
    coding_tree_tth,
2437
    coding_tree_bth,
2438
    coding_tree_ttv,
2439
    coding_tree_btv,
2440
    coding_tree_qt,
2441
};
2442
2443
static int hls_coding_tree(VVCLocalContext *lc,
2444
    int x0, int y0, int cb_width, int cb_height, int qg_on_y, int qg_on_c,
2445
    int cb_sub_div, int cqt_depth, int mtt_depth, int depth_offset, int part_idx,
2446
    VVCSplitMode last_split_mode, VVCTreeType tree_type_curr, VVCModeType mode_type_curr)
2447
19.7M
{
2448
19.7M
    VVCFrameContext *fc             = lc->fc;
2449
19.7M
    const VVCPPS *pps               = fc->ps.pps;
2450
19.7M
    const VVCSH *sh                 = &lc->sc->sh;
2451
19.7M
    const H266RawSliceHeader *rsh   = sh->r;
2452
19.7M
    const int ch_type               = tree_type_curr == DUAL_TREE_CHROMA;
2453
19.7M
    int ret;
2454
19.7M
    VVCAllowedSplit allowed;
2455
2456
19.7M
    if (pps->r->pps_cu_qp_delta_enabled_flag && qg_on_y && cb_sub_div <= sh->cu_qp_delta_subdiv) {
2457
815k
        lc->parse.is_cu_qp_delta_coded = 0;
2458
815k
        lc->parse.cu_qg_top_left_x = x0;
2459
815k
        lc->parse.cu_qg_top_left_y = y0;
2460
815k
    }
2461
19.7M
    if (rsh->sh_cu_chroma_qp_offset_enabled_flag && qg_on_c &&
2462
389k
        cb_sub_div <= sh->cu_chroma_qp_offset_subdiv) {
2463
77.8k
        lc->parse.is_cu_chroma_qp_offset_coded = 0;
2464
77.8k
        memset(lc->parse.chroma_qp_offset, 0, sizeof(lc->parse.chroma_qp_offset));
2465
77.8k
    }
2466
2467
19.7M
    can_split(lc, x0, y0, cb_width, cb_height, mtt_depth, depth_offset, part_idx,
2468
19.7M
        last_split_mode, tree_type_curr, mode_type_curr, &allowed);
2469
19.7M
    if (ff_vvc_split_cu_flag(lc, x0, y0, cb_width, cb_height, ch_type, &allowed)) {
2470
10.3M
        VVCSplitMode split      = ff_vvc_split_mode(lc, x0, y0, cb_width, cb_height, cqt_depth, mtt_depth, ch_type, &allowed);
2471
10.3M
        VVCModeType mode_type   = mode_type_decode(lc, x0, y0, cb_width, cb_height, split, ch_type, mode_type_curr);
2472
2473
10.3M
        VVCTreeType tree_type   = (mode_type == MODE_TYPE_INTRA) ? DUAL_TREE_LUMA : tree_type_curr;
2474
2475
10.3M
        if (split != SPLIT_QT) {
2476
3.44M
            if (!(x0 & 31) && !(y0 & 31) && mtt_depth <= 1)
2477
2.15M
                TAB_MSM(fc, mtt_depth, x0, y0) = split;
2478
3.44M
        }
2479
10.3M
        ret = coding_tree[split - 1](lc, x0, y0, cb_width, cb_height, qg_on_y, qg_on_c,
2480
10.3M
            cb_sub_div, cqt_depth, mtt_depth, depth_offset, tree_type, mode_type);
2481
10.3M
        if (ret < 0)
2482
113k
            return ret;
2483
10.2M
        if (mode_type_curr == MODE_TYPE_ALL && mode_type == MODE_TYPE_INTRA) {
2484
283k
            ret = hls_coding_tree(lc, x0, y0, cb_width, cb_height, 0, qg_on_c, cb_sub_div,
2485
283k
                cqt_depth, mtt_depth, 0, 0, split, DUAL_TREE_CHROMA, mode_type);
2486
283k
            if (ret < 0)
2487
0
                return ret;
2488
283k
        }
2489
10.2M
    } else {
2490
9.42M
        ret = hls_coding_unit(lc, x0, y0, cb_width, cb_height, cqt_depth, tree_type_curr, mode_type_curr);
2491
9.42M
        if (ret < 0)
2492
29.8k
            return ret;
2493
9.42M
    }
2494
2495
19.6M
    return 0;
2496
19.7M
}
2497
2498
static int dual_tree_implicit_qt_split(VVCLocalContext *lc,
2499
    const int x0, const int y0, const int cb_size, const int cqt_depth)
2500
1.14M
{
2501
1.14M
    const VVCSH *sh                 = &lc->sc->sh;
2502
1.14M
    const H266RawSliceHeader *rsh   = sh->r;
2503
1.14M
    const VVCPPS *pps               = lc->fc->ps.pps;
2504
1.14M
    const int cb_subdiv             = 2 * cqt_depth;
2505
1.14M
    int ret;
2506
2507
1.14M
    if (cb_size > 64) {
2508
419k
        #define DUAL_TREE(x, y) do {                                                \
2509
419k
            ret = dual_tree_implicit_qt_split(lc, x, y, cb_size / 2, cqt_depth + 1); \
2510
419k
            if (ret < 0)                                                            \
2511
419k
                return ret;                                                         \
2512
419k
        } while (0)
2513
2514
121k
        const int x1 = x0 + (cb_size / 2);
2515
121k
        const int y1 = y0 + (cb_size / 2);
2516
121k
        if (pps->r->pps_cu_qp_delta_enabled_flag && cb_subdiv <= sh->cu_qp_delta_subdiv) {
2517
1.05k
            lc->parse.is_cu_qp_delta_coded = 0;
2518
1.05k
            lc->parse.cu_qg_top_left_x = x0;
2519
1.05k
            lc->parse.cu_qg_top_left_y = y0;
2520
1.05k
        }
2521
121k
        if (rsh->sh_cu_chroma_qp_offset_enabled_flag && cb_subdiv <= sh->cu_chroma_qp_offset_subdiv) {
2522
223
            lc->parse.is_cu_chroma_qp_offset_coded = 0;
2523
223
            memset(lc->parse.chroma_qp_offset, 0, sizeof(lc->parse.chroma_qp_offset));
2524
223
        }
2525
121k
        DUAL_TREE(x0, y0);
2526
121k
        if (x1 < pps->width)
2527
107k
            DUAL_TREE(x1, y0);
2528
121k
        if (y1 < pps->height)
2529
95.4k
            DUAL_TREE(x0, y1);
2530
121k
        if (x1 < pps->width && y1 < pps->height)
2531
95.3k
            DUAL_TREE(x1, y1);
2532
121k
    #undef DUAL_TREE
2533
1.02M
    } else {
2534
2.03M
        #define CODING_TREE(tree_type) do {                                             \
2535
2.03M
            const int qg_on_y = tree_type == DUAL_TREE_LUMA;                            \
2536
2.03M
            ret = hls_coding_tree(lc, x0, y0, cb_size, cb_size, qg_on_y, !qg_on_y,           \
2537
2.03M
                 cb_subdiv, cqt_depth, 0, 0, 0, SPLIT_NONE, tree_type, MODE_TYPE_ALL);  \
2538
2.03M
            if (ret < 0)                                                                \
2539
2.03M
                return ret;                                                             \
2540
2.03M
        } while (0)
2541
1.02M
        CODING_TREE(DUAL_TREE_LUMA);
2542
1.00M
        CODING_TREE(DUAL_TREE_CHROMA);
2543
1.00M
        #undef CODING_TREE
2544
1.00M
    }
2545
1.12M
    return 0;
2546
1.14M
}
2547
2548
4.52M
#define SET_SAO(elem, value)                            \
2549
4.52M
do {                                                    \
2550
4.08M
    if (!sao_merge_up_flag && !sao_merge_left_flag)     \
2551
4.08M
        sao->elem = value;                              \
2552
4.08M
    else if (sao_merge_left_flag)                       \
2553
910k
        sao->elem = CTB(fc->tab.sao, rx-1, ry).elem;         \
2554
910k
    else if (sao_merge_up_flag)                         \
2555
70.4k
        sao->elem = CTB(fc->tab.sao, rx, ry-1).elem;         \
2556
70.4k
    else                                                \
2557
70.4k
        sao->elem = 0;                                  \
2558
4.08M
} while (0)
2559
2560
static void hls_sao(VVCLocalContext *lc, const int rx, const int ry)
2561
1.57M
{
2562
1.57M
    VVCFrameContext *fc             = lc->fc;
2563
1.57M
    const H266RawSliceHeader *rsh   = lc->sc->sh.r;
2564
1.57M
    int sao_merge_left_flag         = 0;
2565
1.57M
    int sao_merge_up_flag           = 0;
2566
1.57M
    SAOParams *sao                  = &CTB(fc->tab.sao, rx, ry);
2567
1.57M
    int c_idx, i;
2568
2569
1.57M
    if (rsh->sh_sao_luma_used_flag || rsh->sh_sao_chroma_used_flag) {
2570
830k
        if (rx > 0) {
2571
99.9k
            if (lc->ctb_left_flag)
2572
99.9k
                sao_merge_left_flag = ff_vvc_sao_merge_flag_decode(lc);
2573
99.9k
        }
2574
830k
        if (ry > 0 && !sao_merge_left_flag) {
2575
11.7k
            if (lc->ctb_up_flag)
2576
11.7k
                sao_merge_up_flag = ff_vvc_sao_merge_flag_decode(lc);
2577
11.7k
        }
2578
830k
    }
2579
2580
6.28M
    for (c_idx = 0; c_idx < (fc->ps.sps->r->sps_chroma_format_idc ? 3 : 1); c_idx++) {
2581
4.70M
        const int sao_used_flag = !c_idx ? rsh->sh_sao_luma_used_flag : rsh->sh_sao_chroma_used_flag;
2582
4.70M
        if (!sao_used_flag) {
2583
2.23M
            sao->type_idx[c_idx] = SAO_NOT_APPLIED;
2584
2.23M
            continue;
2585
2.23M
        }
2586
2587
2.46M
        if (c_idx == 2) {
2588
818k
            sao->type_idx[2] = sao->type_idx[1];
2589
818k
            sao->eo_class[2] = sao->eo_class[1];
2590
1.64M
        } else {
2591
1.64M
            SET_SAO(type_idx[c_idx], ff_vvc_sao_type_idx_decode(lc));
2592
1.64M
        }
2593
2594
2.46M
        if (sao->type_idx[c_idx] == SAO_NOT_APPLIED)
2595
2.02M
            continue;
2596
2597
2.21M
        for (i = 0; i < 4; i++)
2598
1.77M
            SET_SAO(offset_abs[c_idx][i], ff_vvc_sao_offset_abs_decode(lc));
2599
2600
442k
        if (sao->type_idx[c_idx] == SAO_BAND) {
2601
1.06M
            for (i = 0; i < 4; i++) {
2602
848k
                if (sao->offset_abs[c_idx][i]) {
2603
323k
                    SET_SAO(offset_sign[c_idx][i],
2604
323k
                            ff_vvc_sao_offset_sign_decode(lc));
2605
524k
                } else {
2606
524k
                    sao->offset_sign[c_idx][i] = 0;
2607
524k
                }
2608
848k
            }
2609
212k
            SET_SAO(band_position[c_idx], ff_vvc_sao_band_position_decode(lc));
2610
230k
        } else if (c_idx != 2) {
2611
130k
            SET_SAO(eo_class[c_idx], ff_vvc_sao_eo_class_decode(lc));
2612
130k
        }
2613
2614
        // Inferred parameters
2615
442k
        sao->offset_val[c_idx][0] = 0;
2616
2.21M
        for (i = 0; i < 4; i++) {
2617
1.77M
            sao->offset_val[c_idx][i + 1] = sao->offset_abs[c_idx][i];
2618
1.77M
            if (sao->type_idx[c_idx] == SAO_EDGE) {
2619
921k
                if (i > 1)
2620
460k
                    sao->offset_val[c_idx][i + 1] = -sao->offset_val[c_idx][i + 1];
2621
921k
            } else if (sao->offset_sign[c_idx][i]) {
2622
184k
                sao->offset_val[c_idx][i + 1] = -sao->offset_val[c_idx][i + 1];
2623
184k
            }
2624
1.77M
            sao->offset_val[c_idx][i + 1] *= 1 << (fc->ps.sps->bit_depth - FFMIN(10, fc->ps.sps->bit_depth));
2625
1.77M
        }
2626
442k
    }
2627
1.57M
}
2628
2629
static void alf_params(VVCLocalContext *lc, const int rx, const int ry)
2630
1.57M
{
2631
1.57M
    const VVCFrameContext *fc     = lc->fc;
2632
1.57M
    const H266RawSliceHeader *sh  = lc->sc->sh.r;
2633
1.57M
    ALFParams *alf                = &CTB(fc->tab.alf, rx, ry);
2634
2635
1.57M
    alf->ctb_flag[LUMA] = alf->ctb_flag[CB] = alf->ctb_flag[CR] = 0;
2636
1.57M
    alf->ctb_cc_idc[0] = alf->ctb_cc_idc[1] = 0;
2637
1.57M
    if (sh->sh_alf_enabled_flag) {
2638
122k
        alf->ctb_flag[LUMA] = ff_vvc_alf_ctb_flag(lc, rx, ry, LUMA);
2639
122k
        if (alf->ctb_flag[LUMA]) {
2640
120k
            uint8_t alf_use_aps_flag = 0;
2641
120k
            if (sh->sh_num_alf_aps_ids_luma > 0)
2642
105k
                alf_use_aps_flag = ff_vvc_alf_use_aps_flag(lc);
2643
120k
            if (alf_use_aps_flag) {
2644
103k
                alf->ctb_filt_set_idx_y = 16;
2645
103k
                if (sh->sh_num_alf_aps_ids_luma > 1)
2646
0
                    alf->ctb_filt_set_idx_y += ff_vvc_alf_luma_prev_filter_idx(lc);
2647
103k
            } else {
2648
17.2k
                alf->ctb_filt_set_idx_y = ff_vvc_alf_luma_fixed_filter_idx(lc);
2649
17.2k
            }
2650
120k
        }
2651
366k
        for (int c_idx = CB; c_idx <= CR; c_idx++) {
2652
244k
            const uint8_t alf_enabled_flag =
2653
244k
                c_idx == CB ? sh->sh_alf_cb_enabled_flag : sh->sh_alf_cr_enabled_flag;
2654
244k
            if (alf_enabled_flag) {
2655
213k
                const VVCALF *aps = fc->ps.alf_list[sh->sh_alf_aps_id_chroma];
2656
213k
                alf->ctb_flag[c_idx] = ff_vvc_alf_ctb_flag(lc, rx, ry, c_idx);
2657
213k
                alf->alf_ctb_filter_alt_idx[c_idx - 1] = 0;
2658
213k
                if (alf->ctb_flag[c_idx] && aps->num_chroma_filters > 1)
2659
40.2k
                    alf->alf_ctb_filter_alt_idx[c_idx - 1] = ff_vvc_alf_ctb_filter_alt_idx(lc, c_idx, aps->num_chroma_filters);
2660
213k
            }
2661
244k
        }
2662
122k
    }
2663
1.57M
    if (fc->ps.sps->r->sps_ccalf_enabled_flag) {
2664
772k
        const uint8_t cc_enabled[] = { sh->sh_alf_cc_cb_enabled_flag, sh->sh_alf_cc_cr_enabled_flag };
2665
772k
        const uint8_t cc_aps_id[]  = { sh->sh_alf_cc_cb_aps_id, sh->sh_alf_cc_cr_aps_id };
2666
2.31M
        for (int i = 0; i < 2; i++) {
2667
1.54M
            if (cc_enabled[i]) {
2668
106k
                const VVCALF *aps = fc->ps.alf_list[cc_aps_id[i]];
2669
106k
                alf->ctb_cc_idc[i] = ff_vvc_alf_ctb_cc_idc(lc, rx, ry, i, aps->num_cc_filters[i]);
2670
106k
            }
2671
1.54M
        }
2672
772k
    }
2673
1.57M
}
2674
2675
static void deblock_params(VVCLocalContext *lc, const int rx, const int ry)
2676
1.57M
{
2677
1.57M
    VVCFrameContext *fc = lc->fc;
2678
1.57M
    const VVCSH *sh     = &lc->sc->sh;
2679
1.57M
    CTB(fc->tab.deblock, rx, ry) = sh->deblock;
2680
1.57M
}
2681
2682
static int hls_coding_tree_unit(VVCLocalContext *lc,
2683
    const int x0, const int y0, const int ctu_idx, const int rx, const int ry)
2684
1.57M
{
2685
1.57M
    const VVCFrameContext *fc       = lc->fc;
2686
1.57M
    const VVCSPS *sps               = fc->ps.sps;
2687
1.57M
    const VVCPPS *pps               = fc->ps.pps;
2688
1.57M
    const VVCSH *sh                 = &lc->sc->sh;
2689
1.57M
    const H266RawSliceHeader *rsh   = sh->r;
2690
1.57M
    const unsigned int ctb_size     = sps->ctb_size_y;
2691
1.57M
    int ret                         = 0;
2692
2693
1.57M
    memset(lc->parse.chroma_qp_offset, 0, sizeof(lc->parse.chroma_qp_offset));
2694
2695
1.57M
    hls_sao(lc, x0 >> sps->ctb_log2_size_y, y0 >> sps->ctb_log2_size_y);
2696
1.57M
    alf_params(lc, x0 >> sps->ctb_log2_size_y, y0 >> sps->ctb_log2_size_y);
2697
1.57M
    deblock_params(lc, x0 >> sps->ctb_log2_size_y, y0 >> sps->ctb_log2_size_y);
2698
2699
1.57M
    if (IS_I(rsh) && sps->r->sps_qtbtt_dual_tree_intra_flag)
2700
722k
        ret = dual_tree_implicit_qt_split(lc, x0, y0, ctb_size, 0);
2701
854k
    else
2702
854k
        ret = hls_coding_tree(lc, x0, y0, ctb_size, ctb_size,
2703
854k
            1, 1, 0, 0, 0, 0, 0, SPLIT_NONE, SINGLE_TREE, MODE_TYPE_ALL);
2704
1.57M
    if (ret < 0)
2705
29.8k
        return ret;
2706
2707
1.54M
    if (rx == pps->ctb_to_col_bd[rx + 1] - 1) {
2708
1.44M
        if (ctu_idx == sh->num_ctus_in_curr_slice - 1) {
2709
1.44M
            const int end_of_slice_one_bit = ff_vvc_end_of_slice_flag_decode(lc);
2710
1.44M
            if (!end_of_slice_one_bit)
2711
1.34M
                return AVERROR_INVALIDDATA;
2712
1.44M
        } else {
2713
6.33k
            if (ry == pps->ctb_to_row_bd[ry + 1] - 1) {
2714
1
                const int end_of_tile_one_bit = ff_vvc_end_of_tile_one_bit(lc);
2715
1
                if (!end_of_tile_one_bit)
2716
1
                    return AVERROR_INVALIDDATA;
2717
6.33k
            } else {
2718
6.33k
                if (fc->ps.sps->r->sps_entropy_coding_sync_enabled_flag) {
2719
0
                    const int end_of_subset_one_bit = ff_vvc_end_of_subset_one_bit(lc);
2720
0
                    if (!end_of_subset_one_bit)
2721
0
                        return AVERROR_INVALIDDATA;
2722
0
                }
2723
6.33k
            }
2724
6.33k
        }
2725
1.44M
    }
2726
2727
200k
    return 0;
2728
1.54M
}
2729
2730
static int has_inter_luma(const CodingUnit *cu)
2731
31.2k
{
2732
31.2k
    return cu->pred_mode != MODE_INTRA && cu->pred_mode != MODE_PLT && cu->tree_type != DUAL_TREE_CHROMA;
2733
31.2k
}
2734
2735
static int pred_get_y(const VVCLocalContext *lc, const int y0, const Mv *mv, const int height)
2736
29.8k
{
2737
29.8k
    const VVCPPS *pps = lc->fc->ps.pps;
2738
29.8k
    const int idx     = lc->sc->sh.r->curr_subpic_idx;
2739
29.8k
    const int top     = pps->subpic_y[idx];
2740
29.8k
    const int bottom  = top + pps->subpic_height[idx];
2741
2742
29.8k
    return av_clip(y0 + (mv->y >> 4) + height, top, bottom);
2743
29.8k
}
2744
2745
static void cu_get_max_y(const CodingUnit *cu, int max_y[2][VVC_MAX_REF_ENTRIES], const VVCLocalContext *lc)
2746
24.9k
{
2747
24.9k
    const VVCFrameContext *fc   = lc->fc;
2748
24.9k
    const PredictionUnit *pu    = &cu->pu;
2749
2750
24.9k
    if (pu->merge_gpm_flag) {
2751
3.63k
        for (int i = 0; i < FF_ARRAY_ELEMS(pu->gpm_mv); i++) {
2752
2.42k
            const MvField *mvf  = pu->gpm_mv + i;
2753
2.42k
            const int lx        = mvf->pred_flag - PF_L0;
2754
2.42k
            const int idx       = mvf->ref_idx[lx];
2755
2.42k
            const int y         = pred_get_y(lc, cu->y0, mvf->mv + lx, cu->cb_height);
2756
2757
2.42k
            max_y[lx][idx]      = FFMAX(max_y[lx][idx], y);
2758
2.42k
        }
2759
23.7k
    } else {
2760
23.7k
        const MotionInfo *mi    = &pu->mi;
2761
23.7k
        const int max_dmvr_off  = (!pu->inter_affine_flag && pu->dmvr_flag) ? 2 : 0;
2762
23.7k
        const int sbw           = cu->cb_width / mi->num_sb_x;
2763
23.7k
        const int sbh           = cu->cb_height / mi->num_sb_y;
2764
47.7k
        for (int sby = 0; sby < mi->num_sb_y; sby++) {
2765
48.6k
            for (int sbx = 0; sbx < mi->num_sb_x; sbx++) {
2766
24.6k
                const int x0        = cu->x0 + sbx * sbw;
2767
24.6k
                const int y0        = cu->y0 + sby * sbh;
2768
24.6k
                const MvField *mvf  = ff_vvc_get_mvf(fc, x0, y0);
2769
73.8k
                for (int lx = 0; lx < 2; lx++) {
2770
49.2k
                    const PredFlag mask = 1 << lx;
2771
49.2k
                    if (mvf->pred_flag & mask) {
2772
27.4k
                        const int idx   = mvf->ref_idx[lx];
2773
27.4k
                        const int y     = pred_get_y(lc, y0, mvf->mv + lx, sbh);
2774
2775
27.4k
                        max_y[lx][idx]  = FFMAX(max_y[lx][idx], y + max_dmvr_off);
2776
27.4k
                    }
2777
49.2k
                }
2778
24.6k
            }
2779
24.0k
        }
2780
23.7k
    }
2781
24.9k
}
2782
2783
static void ctu_get_pred(VVCLocalContext *lc, const int rs)
2784
200k
{
2785
200k
    const VVCFrameContext *fc       = lc->fc;
2786
200k
    const H266RawSliceHeader *rsh   = lc->sc->sh.r;
2787
200k
    CTU *ctu                        = fc->tab.ctus + rs;
2788
200k
    const CodingUnit *cu            = fc->tab.cus[rs];
2789
2790
200k
    ctu->has_dmvr = 0;
2791
2792
200k
    if (IS_I(rsh))
2793
179k
        return;
2794
2795
61.4k
    for (int lx = 0; lx < 2; lx++)
2796
40.9k
        memset(ctu->max_y[lx], -1, sizeof(ctu->max_y[0][0]) * rsh->num_ref_idx_active[lx]);
2797
2798
51.7k
    while (cu) {
2799
31.2k
        if (has_inter_luma(cu)) {
2800
24.9k
            cu_get_max_y(cu, ctu->max_y, lc);
2801
24.9k
            ctu->has_dmvr |= cu->pu.dmvr_flag;
2802
24.9k
        }
2803
31.2k
        cu = cu->next;
2804
31.2k
    }
2805
20.4k
    ctu->max_y_idx[0] = ctu->max_y_idx[1] = 0;
2806
20.4k
}
2807
2808
int ff_vvc_coding_tree_unit(VVCLocalContext *lc,
2809
    const int ctu_idx, const int rs, const int rx, const int ry)
2810
1.57M
{
2811
1.57M
    const VVCFrameContext *fc   = lc->fc;
2812
1.57M
    const VVCSPS *sps           = fc->ps.sps;
2813
1.57M
    const VVCPPS *pps           = fc->ps.pps;
2814
1.57M
    const int x_ctb             = rx << sps->ctb_log2_size_y;
2815
1.57M
    const int y_ctb             = ry << sps->ctb_log2_size_y;
2816
1.57M
    const int ctb_size          = 1 << sps->ctb_log2_size_y << sps->ctb_log2_size_y;
2817
1.57M
    EntryPoint* ep              = lc->ep;
2818
1.57M
    int ret;
2819
2820
1.57M
    if (rx == pps->ctb_to_col_bd[rx]) {
2821
1.47M
        ep->num_hmvp = 0;
2822
1.47M
        ep->num_hmvp_ibc = 0;
2823
1.47M
        ep->is_first_qg = ry == pps->ctb_to_row_bd[ry] || !ctu_idx;
2824
1.47M
    }
2825
2826
1.57M
    lc->coeffs = fc->tab.coeffs + rs * ctb_size * VVC_MAX_SAMPLE_ARRAYS;
2827
1.57M
    lc->cu     = NULL;
2828
2829
1.57M
    ff_vvc_cabac_init(lc, ctu_idx, rx, ry);
2830
1.57M
    ff_vvc_decode_neighbour(lc, x_ctb, y_ctb, rx, ry, rs);
2831
1.57M
    ret = hls_coding_tree_unit(lc, x_ctb, y_ctb, ctu_idx, rx, ry);
2832
1.57M
    if (ret < 0)
2833
1.37M
        return ret;
2834
200k
    ctu_get_pred(lc, rs);
2835
2836
200k
    return 0;
2837
1.57M
}
2838
2839
void ff_vvc_decode_neighbour(VVCLocalContext *lc, const int x_ctb, const int y_ctb,
2840
    const int rx, const int ry, const int rs)
2841
2.27M
{
2842
2.27M
    VVCFrameContext *fc = lc->fc;
2843
2.27M
    const int ctb_size         = fc->ps.sps->ctb_size_y;
2844
2845
2.27M
    lc->end_of_tiles_x = fc->ps.pps->width;
2846
2.27M
    lc->end_of_tiles_y = fc->ps.pps->height;
2847
2.27M
    if (fc->ps.pps->ctb_to_col_bd[rx] != fc->ps.pps->ctb_to_col_bd[rx + 1])
2848
1.93M
        lc->end_of_tiles_x = FFMIN(x_ctb + ctb_size, lc->end_of_tiles_x);
2849
2.27M
    if (fc->ps.pps->ctb_to_row_bd[ry] != fc->ps.pps->ctb_to_row_bd[ry + 1])
2850
1.95M
        lc->end_of_tiles_y = FFMIN(y_ctb + ctb_size, lc->end_of_tiles_y);
2851
2852
2.27M
    lc->boundary_flags = 0;
2853
2.27M
    if (rx > 0 && fc->ps.pps->ctb_to_col_bd[rx] != fc->ps.pps->ctb_to_col_bd[rx - 1])
2854
31
        lc->boundary_flags |= BOUNDARY_LEFT_TILE;
2855
2.27M
    if (rx > 0 && fc->tab.slice_idx[rs] != fc->tab.slice_idx[rs - 1])
2856
0
        lc->boundary_flags |= BOUNDARY_LEFT_SLICE;
2857
2.27M
    if (ry > 0 && fc->ps.pps->ctb_to_row_bd[ry] != fc->ps.pps->ctb_to_row_bd[ry - 1])
2858
25
        lc->boundary_flags |= BOUNDARY_UPPER_TILE;
2859
2.27M
    if (ry > 0 && fc->tab.slice_idx[rs] != fc->tab.slice_idx[rs - fc->ps.pps->ctb_width])
2860
0
        lc->boundary_flags |= BOUNDARY_UPPER_SLICE;
2861
2.27M
    if (fc->ps.sps->r->sps_subpic_ctu_top_left_x[lc->sc->sh.r->curr_subpic_idx] == rx)
2862
1.94M
        lc->boundary_flags |= BOUNDARY_LEFT_SUBPIC;
2863
2.27M
    if (fc->ps.sps->r->sps_subpic_ctu_top_left_y[lc->sc->sh.r->curr_subpic_idx] == ry)
2864
1.95M
        lc->boundary_flags |= BOUNDARY_UPPER_SUBPIC;
2865
2.27M
    lc->ctb_left_flag = rx > 0 && !(lc->boundary_flags & BOUNDARY_LEFT_TILE);
2866
2.27M
    lc->ctb_up_flag   = ry > 0 && !(lc->boundary_flags & BOUNDARY_UPPER_TILE) && !(lc->boundary_flags & BOUNDARY_UPPER_SLICE);
2867
2.27M
    lc->ctb_up_right_flag = lc->ctb_up_flag && (fc->ps.pps->ctb_to_col_bd[rx] == fc->ps.pps->ctb_to_col_bd[rx + 1]) &&
2868
294k
        (fc->ps.pps->ctb_to_row_bd[ry] == fc->ps.pps->ctb_to_row_bd[ry - 1]);
2869
2.27M
    lc->ctb_up_left_flag = lc->ctb_left_flag && lc->ctb_up_flag;
2870
2.27M
}
2871
2872
void ff_vvc_set_neighbour_available(VVCLocalContext *lc,
2873
    const int x0, const int y0, const int w, const int h)
2874
14.4M
{
2875
14.4M
    const int log2_ctb_size = lc->fc->ps.sps->ctb_log2_size_y;
2876
14.4M
    const int x0b = av_zero_extend(x0, log2_ctb_size);
2877
14.4M
    const int y0b = av_zero_extend(y0, log2_ctb_size);
2878
2879
14.4M
    lc->na.cand_up       = (lc->ctb_up_flag   || y0b);
2880
14.4M
    lc->na.cand_left     = (lc->ctb_left_flag || x0b);
2881
14.4M
    lc->na.cand_up_left  = (x0b || y0b) ? lc->na.cand_left && lc->na.cand_up : lc->ctb_up_left_flag;
2882
14.4M
    lc->na.cand_up_right_sap =
2883
14.4M
            (x0b + w == 1 << log2_ctb_size) ? lc->ctb_up_right_flag && !y0b : lc->na.cand_up;
2884
14.4M
    lc->na.cand_up_right = lc->na.cand_up_right_sap && (x0 + w) < lc->end_of_tiles_x;
2885
14.4M
}
2886
2887
void ff_vvc_ctu_free_cus(CodingUnit **cus)
2888
2.94M
{
2889
12.3M
    while (*cus) {
2890
9.42M
        CodingUnit *cu          = *cus;
2891
9.42M
        TransformUnit **head    = &cu->tus.head;
2892
2893
9.42M
        *cus = cu->next;
2894
2895
19.0M
        while (*head) {
2896
9.62M
            TransformUnit *tu = *head;
2897
9.62M
            *head = tu->next;
2898
9.62M
            av_refstruct_unref(&tu);
2899
9.62M
        }
2900
9.42M
        cu->tus.tail = NULL;
2901
2902
9.42M
        av_refstruct_unref(&cu);
2903
9.42M
    }
2904
2.94M
}
2905
2906
int ff_vvc_get_qPy(const VVCFrameContext *fc, const int xc, const int yc)
2907
13.7M
{
2908
13.7M
    const int min_cb_log2_size_y = fc->ps.sps->min_cb_log2_size_y;
2909
13.7M
    const int x                  = xc >> min_cb_log2_size_y;
2910
13.7M
    const int y                  = yc >> min_cb_log2_size_y;
2911
13.7M
    return fc->tab.qp[LUMA][x + y * fc->ps.pps->min_cb_width];
2912
13.7M
}
2913
2914
void ff_vvc_ep_init_stat_coeff(EntryPoint *ep,
2915
    const int bit_depth, const int persistent_rice_adaptation_enabled_flag)
2916
1.47M
{
2917
5.88M
    for (size_t i = 0; i < FF_ARRAY_ELEMS(ep->stat_coeff); ++i) {
2918
4.41M
        ep->stat_coeff[i] =
2919
4.41M
            persistent_rice_adaptation_enabled_flag ? 2 * (av_log2(bit_depth - 10)) : 0;
2920
4.41M
    }
2921
1.47M
}
2922
2923
void ff_vvc_channel_range(int *start, int *end, const VVCTreeType tree_type, const uint8_t chroma_format_idc)
2924
579k
{
2925
579k
    const bool has_chroma = chroma_format_idc && tree_type != DUAL_TREE_LUMA;
2926
579k
    const bool has_luma   = tree_type != DUAL_TREE_CHROMA;
2927
2928
579k
    *start = has_luma   ? LUMA : CB;
2929
579k
    *end   = has_chroma ? VVC_MAX_SAMPLE_ARRAYS : CB;
2930
579k
}