Coverage Report

Created: 2026-02-14 06:59

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
5.23M
#define TAB_MSM(fc, depth, x, y) fc->tab.msm[(depth)][((y) >> 5) * fc->ps.pps->width32 + ((x) >> 5)]
35
3.40M
#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
9.56M
{
45
9.56M
    const int x_tb      = tb->x0 >> MIN_TU_LOG2;
46
9.56M
    const int y_tb      = tb->y0 >> MIN_TU_LOG2;
47
9.56M
    const int hs        = fc->ps.sps->hshift[tb->c_idx];
48
9.56M
    const int vs        = fc->ps.sps->vshift[tb->c_idx];
49
9.56M
    const int is_chroma = tb->c_idx != 0;
50
9.56M
    const int width     = FFMAX(1, tb->tb_width >> (MIN_TU_LOG2 - hs));
51
9.56M
    const int end       = y_tb + FFMAX(1, tb->tb_height >> (MIN_TU_LOG2 - vs));
52
53
35.0M
    for (int y = y_tb; y < end; y++) {
54
25.4M
        const int off = y * fc->ps.pps->min_tu_width + x_tb;
55
25.4M
        memset(fc->tab.tb_width [is_chroma] + off, tb->tb_width,  width);
56
25.4M
        memset(fc->tab.tb_height[is_chroma] + off, tb->tb_height, width);
57
25.4M
    }
58
9.56M
}
59
60
static void set_tb_tab(uint8_t *tab, uint8_t v, const VVCFrameContext *fc,
61
    const TransformBlock *tb)
62
17.2M
{
63
17.2M
    const int width  = tb->tb_width  << fc->ps.sps->hshift[tb->c_idx];
64
17.2M
    const int height = tb->tb_height << fc->ps.sps->vshift[tb->c_idx];
65
66
66.9M
    for (int h = 0; h < height; h += MIN_TU_SIZE) {
67
49.7M
        const int y = (tb->y0 + h) >> MIN_TU_LOG2;
68
49.7M
        const int off = y * fc->ps.pps->min_tu_width + (tb->x0 >> MIN_TU_LOG2);
69
49.7M
        const int w = FFMAX(1, width >> MIN_TU_LOG2);
70
49.7M
        memset(tab + off, v, w);
71
49.7M
    }
72
17.2M
}
73
74
// 8.7.1 Derivation process for quantization parameters
75
static int get_qp_y_pred(const VVCLocalContext *lc)
76
803k
{
77
803k
    const VVCFrameContext *fc     = lc->fc;
78
803k
    const VVCSPS *sps       = fc->ps.sps;
79
803k
    const VVCPPS *pps       = fc->ps.pps;
80
803k
    const CodingUnit *cu    = lc->cu;
81
803k
    const int ctb_log2_size = sps->ctb_log2_size_y;
82
803k
    const int ctb_size_mask = (1 << ctb_log2_size) - 1;
83
803k
    const int xQg           = lc->parse.cu_qg_top_left_x;
84
803k
    const int yQg           = lc->parse.cu_qg_top_left_y;
85
803k
    const int min_cb_width  = fc->ps.pps->min_cb_width;
86
803k
    const int x_cb          = cu->x0 >> sps->min_cb_log2_size_y;
87
803k
    const int y_cb          = cu->y0 >> sps->min_cb_log2_size_y;
88
803k
    const int rx            = cu->x0 >> ctb_log2_size;
89
803k
    const int ry            = cu->y0 >> ctb_log2_size;
90
803k
    const int in_same_ctb_a = ((xQg - 1) >> ctb_log2_size) == rx && (yQg >> ctb_log2_size) == ry;
91
803k
    const int in_same_ctb_b = (xQg >> ctb_log2_size) == rx && ((yQg - 1) >> ctb_log2_size) == ry;
92
803k
    int qPy_pred, qPy_a, qPy_b;
93
94
803k
    if (lc->na.cand_up) {
95
1.40k
        const int first_qg_in_ctu = !(xQg & ctb_size_mask) &&  !(yQg & ctb_size_mask);
96
1.40k
        const int qPy_up          = fc->tab.qp[LUMA][x_cb + (y_cb - 1) * min_cb_width];
97
1.40k
        if (first_qg_in_ctu && pps->ctb_to_col_bd[xQg >> ctb_log2_size] == xQg >> ctb_log2_size)
98
8
            return qPy_up;
99
1.40k
    }
100
101
    // qPy_pred
102
803k
    qPy_pred = lc->ep->is_first_qg ? lc->sc->sh.slice_qp_y : lc->ep->qp_y;
103
104
    // qPy_b
105
803k
    if (!lc->na.cand_up || !in_same_ctb_b)
106
802k
        qPy_b = qPy_pred;
107
1.28k
    else
108
1.28k
        qPy_b = fc->tab.qp[LUMA][x_cb + (y_cb - 1) * min_cb_width];
109
110
    // qPy_a
111
803k
    if (!lc->na.cand_left || !in_same_ctb_a)
112
802k
        qPy_a = qPy_pred;
113
1.27k
    else
114
1.27k
        qPy_a = fc->tab.qp[LUMA][(x_cb - 1) + y_cb * min_cb_width];
115
116
803k
    av_assert2(qPy_a >= -fc->ps.sps->qp_bd_offset && qPy_a <= 63);
117
803k
    av_assert2(qPy_b >= -fc->ps.sps->qp_bd_offset && qPy_b <= 63);
118
119
803k
    return (qPy_a + qPy_b + 1) >> 1;
120
803k
}
121
122
static void set_cb_tab(const VVCLocalContext *lc, uint8_t *tab, const uint8_t v)
123
53.1M
{
124
53.1M
    const VVCFrameContext *fc   = lc->fc;
125
53.1M
    const VVCPPS *pps           = fc->ps.pps;
126
53.1M
    const CodingUnit *cu        = lc->cu;
127
53.1M
    const int log2_min_cb_size  = fc->ps.sps->min_cb_log2_size_y;
128
53.1M
    const int x_cb              = cu->x0 >> log2_min_cb_size;
129
53.1M
    const int y_cb              = cu->y0 >> log2_min_cb_size;
130
53.1M
    const int cb_width          = cu->cb_width;
131
53.1M
    const int cb_height         = cu->cb_height;
132
53.1M
    int x                       = y_cb * pps->min_cb_width + x_cb;
133
134
190M
    for (int y = 0; y < (cb_height >> log2_min_cb_size); y++) {
135
137M
        const int width = cb_width >> log2_min_cb_size;
136
137
137M
        memset(&tab[x], v, width);
138
137M
        x += pps->min_cb_width;
139
137M
    }
140
53.1M
}
141
142
static int set_qp_y(VVCLocalContext *lc, const int x0, const int y0, const int has_qp_delta)
143
6.04M
{
144
6.04M
    const VVCSPS *sps   = lc->fc->ps.sps;
145
6.04M
    EntryPoint *ep      = lc->ep;
146
6.04M
    CodingUnit *cu      = lc->cu;
147
6.04M
    int cu_qp_delta     = 0;
148
149
6.04M
    if (!lc->fc->ps.pps->r->pps_cu_qp_delta_enabled_flag) {
150
3.92M
        ep->qp_y = lc->sc->sh.slice_qp_y;
151
3.92M
    } else if (ep->is_first_qg || (lc->parse.cu_qg_top_left_x == x0 && lc->parse.cu_qg_top_left_y == y0)) {
152
803k
        ep->qp_y = get_qp_y_pred(lc);
153
803k
        ep->is_first_qg = 0;
154
803k
    }
155
156
6.04M
    if (has_qp_delta) {
157
775k
        const int cu_qp_delta_abs = ff_vvc_cu_qp_delta_abs(lc);
158
159
775k
        if (cu_qp_delta_abs)
160
590k
            cu_qp_delta = ff_vvc_cu_qp_delta_sign_flag(lc) ? -cu_qp_delta_abs : cu_qp_delta_abs;
161
775k
        if (cu_qp_delta > (31 + sps->qp_bd_offset / 2) || cu_qp_delta < -(32 + sps->qp_bd_offset / 2))
162
2.32k
            return AVERROR_INVALIDDATA;
163
772k
        lc->parse.is_cu_qp_delta_coded = 1;
164
165
772k
        if (cu_qp_delta) {
166
588k
            int off = sps->qp_bd_offset;
167
588k
            ep->qp_y = FFUMOD(ep->qp_y + cu_qp_delta + 64 + 2 * off, 64 + off) - off;
168
588k
        }
169
772k
    }
170
171
6.04M
    set_cb_tab(lc, lc->fc->tab.qp[LUMA], ep->qp_y);
172
6.04M
    cu->qp[LUMA] = ep->qp_y;
173
174
6.04M
    return 0;
175
6.04M
}
176
177
static void set_qp_c_tab(const VVCLocalContext *lc, const TransformUnit *tu, const TransformBlock *tb)
178
7.02M
{
179
7.02M
    const int is_jcbcr = tu->joint_cbcr_residual_flag && tu->coded_flag[CB] && tu->coded_flag[CR];
180
7.02M
    const int idx = is_jcbcr ? JCBCR : tb->c_idx;
181
182
7.02M
    set_tb_tab(lc->fc->tab.qp[tb->c_idx], lc->cu->qp[idx], lc->fc, tb);
183
7.02M
}
184
185
static void set_qp_c(VVCLocalContext *lc)
186
8.38M
{
187
8.38M
    const VVCFrameContext *fc       = lc->fc;
188
8.38M
    const VVCSPS *sps               = fc->ps.sps;
189
8.38M
    const VVCPPS *pps               = fc->ps.pps;
190
8.38M
    const H266RawSliceHeader *rsh   = lc->sc->sh.r;
191
8.38M
    CodingUnit *cu                  = lc->cu;
192
8.38M
    const int x_center              = cu->x0 + cu->cb_width  / 2;
193
8.38M
    const int y_center              = cu->y0 + cu->cb_height / 2;
194
8.38M
    const int single_tree           = cu->tree_type == SINGLE_TREE;
195
8.38M
    const int qp_luma               = (single_tree ? lc->ep->qp_y : ff_vvc_get_qPy(fc, x_center, y_center)) + sps->qp_bd_offset;
196
8.38M
    const int qp_chroma             = av_clip(qp_luma, 0, MAX_QP + sps->qp_bd_offset);
197
8.38M
    const int sh_chroma_qp_offset[] = {
198
8.38M
        rsh->sh_cb_qp_offset,
199
8.38M
        rsh->sh_cr_qp_offset,
200
8.38M
        rsh->sh_joint_cbcr_qp_offset,
201
8.38M
    };
202
8.38M
    int qp;
203
204
33.3M
    for (int i = CB - 1; i < CR + sps->r->sps_joint_cbcr_enabled_flag; i++) {
205
25.0M
        qp = sps->chroma_qp_table[i][qp_chroma];
206
25.0M
        qp = qp + pps->chroma_qp_offset[i] + sh_chroma_qp_offset[i] + lc->parse.chroma_qp_offset[i];
207
25.0M
        qp = av_clip(qp, -sps->qp_bd_offset, MAX_QP) + sps->qp_bd_offset;
208
25.0M
        cu->qp[i + 1] = qp;
209
25.0M
    }
210
8.38M
}
211
212
static TransformUnit* alloc_tu(VVCFrameContext *fc, CodingUnit *cu)
213
8.66M
{
214
8.66M
    TransformUnit *tu = av_refstruct_pool_get(fc->tu_pool);
215
8.66M
    if (!tu)
216
0
        return NULL;
217
218
8.66M
    tu->next = NULL;
219
220
8.66M
    if (cu->tus.tail)
221
167k
        cu->tus.tail->next =  tu;
222
8.49M
    else
223
8.49M
        cu->tus.head = tu;
224
8.66M
    cu->tus.tail = tu;
225
226
8.66M
    return tu;
227
8.66M
}
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
8.66M
{
231
8.66M
    TransformUnit *tu = alloc_tu(fc, cu);
232
233
8.66M
    if (!tu)
234
0
        return NULL;
235
236
8.66M
    tu->x0 = x0;
237
8.66M
    tu->y0 = y0;
238
8.66M
    tu->width = tu_width;
239
8.66M
    tu->height = tu_height;
240
8.66M
    tu->joint_cbcr_residual_flag = 0;
241
8.66M
    memset(tu->coded_flag, 0, sizeof(tu->coded_flag));
242
8.66M
    tu->avail[LUMA] = tu->avail[CHROMA] = 0;
243
8.66M
    tu->nb_tbs = 0;
244
245
8.66M
    return tu;
246
8.66M
}
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
13.0M
{
251
13.0M
    TransformBlock *tb;
252
253
13.0M
    tb = &tu->tbs[tu->nb_tbs++];
254
13.0M
    tb->has_coeffs = 0;
255
13.0M
    tb->x0 = x0;
256
13.0M
    tb->y0 = y0;
257
13.0M
    tb->tb_width  = tb_width;
258
13.0M
    tb->tb_height = tb_height;
259
13.0M
    tb->log2_tb_width  = av_log2(tb_width);
260
13.0M
    tb->log2_tb_height = av_log2(tb_height);
261
262
13.0M
    tb->max_scan_x = tb->max_scan_y = 0;
263
13.0M
    tb->min_scan_x = tb->min_scan_y = 0;
264
265
13.0M
    tb->c_idx = c_idx;
266
13.0M
    tb->ts = 0;
267
13.0M
    tb->coeffs = lc->coeffs;
268
13.0M
    lc->coeffs += tb_width * tb_height;
269
13.0M
    tu->avail[!!c_idx] = true;
270
13.0M
    return tb;
271
13.0M
}
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
5.86M
{
276
5.86M
    uint8_t tu_y_coded_flag = 0;
277
5.86M
    const VVCSPS *sps       = lc->fc->ps.sps;
278
5.86M
    CodingUnit *cu          = lc->cu;
279
280
5.86M
    if (!is_sbt_not_coded) {
281
5.86M
        int has_y_coded_flag = sub_tu_index < cu->num_intra_subpartitions - 1 || !lc->parse.infer_tu_cbf_luma;
282
5.86M
        if (!is_isp) {
283
5.63M
            const int is_large = cu->cb_width > sps->max_tb_size_y || cu->cb_height > sps->max_tb_size_y;
284
5.63M
            has_y_coded_flag = (cu->pred_mode == MODE_INTRA && !cu->act_enabled_flag) || is_chroma_coded || is_large;
285
5.63M
        }
286
5.86M
        tu_y_coded_flag = has_y_coded_flag ? ff_vvc_tu_y_coded_flag(lc) : 1;
287
5.86M
    }
288
5.86M
    if (is_isp)
289
231k
        lc->parse.infer_tu_cbf_luma = lc->parse.infer_tu_cbf_luma && !tu_y_coded_flag;
290
5.86M
    return tu_y_coded_flag;
291
5.86M
}
292
293
static void chroma_qp_offset_decode(VVCLocalContext *lc, const int is_128, const int is_chroma_coded)
294
3.48M
{
295
3.48M
    const VVCPPS *pps               = lc->fc->ps.pps;
296
3.48M
    const H266RawSliceHeader *rsh   = lc->sc->sh.r;
297
298
3.48M
    if ((is_128 || is_chroma_coded) &&
299
1.29M
        rsh->sh_cu_chroma_qp_offset_enabled_flag && !lc->parse.is_cu_chroma_qp_offset_coded) {
300
22.6k
        const int cu_chroma_qp_offset_flag = ff_vvc_cu_chroma_qp_offset_flag(lc);
301
22.6k
        if (cu_chroma_qp_offset_flag) {
302
10.5k
            int cu_chroma_qp_offset_idx = 0;
303
10.5k
            if (pps->r->pps_chroma_qp_offset_list_len_minus1 > 0)
304
3.61k
                cu_chroma_qp_offset_idx = ff_vvc_cu_chroma_qp_offset_idx(lc);
305
42.2k
            for (int i = CB - 1; i < JCBCR; i++)
306
31.6k
                lc->parse.chroma_qp_offset[i] = pps->chroma_qp_offset_list[cu_chroma_qp_offset_idx][i];
307
12.0k
        } else {
308
12.0k
            memset(lc->parse.chroma_qp_offset, 0, sizeof(lc->parse.chroma_qp_offset));
309
12.0k
        }
310
22.6k
        lc->parse.is_cu_chroma_qp_offset_coded = 1;
311
22.6k
    }
312
3.48M
}
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
8.42M
{
316
8.42M
    VVCFrameContext *fc = lc->fc;
317
8.42M
    const VVCSPS *sps   = fc->ps.sps;
318
8.42M
    const VVCPPS *pps   = fc->ps.pps;
319
8.42M
    CodingUnit *cu      = lc->cu;
320
8.42M
    TransformUnit *tu   = add_tu(fc, cu, x0, y0, tu_width, tu_height);
321
8.42M
    const int min_cb_width      = pps->min_cb_width;
322
8.42M
    const VVCTreeType tree_type = cu->tree_type;
323
8.42M
    const int is_128            = cu->cb_width > 64 || cu->cb_height > 64;
324
8.42M
    const int is_isp            = cu->isp_split_type != ISP_NO_SPLIT;
325
8.42M
    const int is_isp_last_tu    = is_isp && (sub_tu_index == cu->num_intra_subpartitions - 1);
326
8.42M
    const int is_sbt_not_coded  = cu->sbt_flag &&
327
13.1k
        ((sub_tu_index == 0 && cu->sbt_pos_flag) || (sub_tu_index == 1 && !cu->sbt_pos_flag));
328
8.42M
    const int chroma_available  = tree_type != DUAL_TREE_LUMA && sps->r->sps_chroma_format_idc &&
329
3.47M
        (!is_isp || is_isp_last_tu);
330
8.42M
    int ret, xc, yc, wc, hc, is_chroma_coded;
331
332
8.42M
    if (!tu)
333
0
        return AVERROR_INVALIDDATA;
334
335
8.42M
    if (tree_type == SINGLE_TREE && is_isp_last_tu) {
336
32.1k
        const int x_cu = x0 >> fc->ps.sps->min_cb_log2_size_y;
337
32.1k
        const int y_cu = y0 >> fc->ps.sps->min_cb_log2_size_y;
338
32.1k
        xc = SAMPLE_CTB(fc->tab.cb_pos_x[ch_type],  x_cu, y_cu);
339
32.1k
        yc = SAMPLE_CTB(fc->tab.cb_pos_y[ch_type],  x_cu, y_cu);
340
32.1k
        wc = SAMPLE_CTB(fc->tab.cb_width[ch_type],  x_cu, y_cu);
341
32.1k
        hc = SAMPLE_CTB(fc->tab.cb_height[ch_type], x_cu, y_cu);
342
8.39M
    } else {
343
8.39M
        xc = x0, yc = y0, wc = tu_width, hc = tu_height;
344
8.39M
    }
345
346
8.42M
    if (chroma_available && !is_sbt_not_coded) {
347
3.39M
        tu->coded_flag[CB] = ff_vvc_tu_cb_coded_flag(lc);
348
3.39M
        tu->coded_flag[CR] = ff_vvc_tu_cr_coded_flag(lc, tu->coded_flag[CB]);
349
3.39M
    }
350
351
8.42M
    is_chroma_coded = chroma_available && (tu->coded_flag[CB] || tu->coded_flag[CR]);
352
353
8.42M
    if (tree_type != DUAL_TREE_CHROMA) {
354
5.86M
        int has_qp_delta;
355
5.86M
        tu->coded_flag[LUMA] = tu_y_coded_flag_decode(lc, is_sbt_not_coded, sub_tu_index, is_isp, is_chroma_coded);
356
5.86M
        has_qp_delta = (is_128 || tu->coded_flag[LUMA] || is_chroma_coded) &&
357
5.23M
            pps->r->pps_cu_qp_delta_enabled_flag && !lc->parse.is_cu_qp_delta_coded;
358
5.86M
        ret = set_qp_y(lc, x0, y0, has_qp_delta);
359
5.86M
        if (ret < 0)
360
2.31k
            return ret;
361
5.86M
        add_tb(tu, lc, x0, y0, tu_width, tu_height, LUMA);
362
5.86M
    }
363
8.42M
    if (tree_type != DUAL_TREE_LUMA) {
364
3.48M
        chroma_qp_offset_decode(lc, is_128, is_chroma_coded);
365
3.48M
        if (chroma_available) {
366
3.39M
            const int hs = sps->hshift[CHROMA];
367
3.39M
            const int vs = sps->vshift[CHROMA];
368
3.39M
            add_tb(tu, lc, xc, yc, wc >> hs, hc >> vs, CB);
369
3.39M
            add_tb(tu, lc, xc, yc, wc >> hs, hc >> vs, CR);
370
3.39M
        }
371
3.48M
    }
372
8.42M
    if (sps->r->sps_joint_cbcr_enabled_flag && ((cu->pred_mode == MODE_INTRA &&
373
8.00M
        (tu->coded_flag[CB] || tu->coded_flag[CR])) ||
374
7.07M
        (tu->coded_flag[CB] && tu->coded_flag[CR])) &&
375
1.23M
        chroma_available) {
376
1.23M
        tu->joint_cbcr_residual_flag = ff_vvc_tu_joint_cbcr_residual_flag(lc, tu->coded_flag[1], tu->coded_flag[2]);
377
1.23M
    }
378
379
21.0M
    for (int i = 0; i < tu->nb_tbs; i++) {
380
12.6M
        TransformBlock *tb  = &tu->tbs[i];
381
12.6M
        const int is_chroma = tb->c_idx != LUMA;
382
12.6M
        tb->has_coeffs = tu->coded_flag[tb->c_idx];
383
12.6M
        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
12.6M
        if (tb->has_coeffs) {
386
6.84M
            tb->ts = cu->bdpcm_flag[tb->c_idx];
387
6.84M
            if (sps->r->sps_transform_skip_enabled_flag && !cu->bdpcm_flag[tb->c_idx] &&
388
5.15M
                tb->tb_width <= sps->max_ts_size && tb->tb_height <= sps->max_ts_size &&
389
4.72M
                !cu->sbt_flag && (is_chroma || !is_isp)) {
390
4.66M
                tb->ts = ff_vvc_transform_skip_flag(lc, is_chroma);
391
4.66M
            }
392
6.84M
            ret = ff_vvc_residual_coding(lc, tb);
393
6.84M
            if (ret < 0)
394
0
                return ret;
395
6.84M
            set_tb_tab(fc->tab.tu_coded_flag[tb->c_idx], tu->coded_flag[tb->c_idx], fc, tb);
396
6.84M
        } else if (cu->act_enabled_flag) {
397
319k
            memset(tb->coeffs, 0, tb->tb_width * tb->tb_height * sizeof(*tb->coeffs));
398
319k
        }
399
12.6M
        if (tb->c_idx != CR)
400
9.26M
            set_tb_size(fc, tb);
401
12.6M
        if (tb->c_idx == CB)
402
3.39M
            set_tb_tab(fc->tab.tu_joint_cbcr_residual_flag, tu->joint_cbcr_residual_flag, fc, tb);
403
12.6M
    }
404
405
8.42M
    return 0;
406
8.42M
}
407
408
static int hls_transform_tree(VVCLocalContext *lc, int x0, int y0,int tu_width, int tu_height, int ch_type)
409
8.25M
{
410
8.25M
    const CodingUnit *cu = lc->cu;
411
8.25M
    const VVCSPS *sps = lc->fc->ps.sps;
412
8.25M
    int ret;
413
414
8.25M
    lc->parse.infer_tu_cbf_luma = 1;
415
8.25M
    if (cu->isp_split_type == ISP_NO_SPLIT && !cu->sbt_flag) {
416
8.18M
        if (tu_width > sps->max_tb_size_y || tu_height > sps->max_tb_size_y) {
417
0
            const int ver_split_first = tu_width > sps->max_tb_size_y && tu_width > tu_height;
418
0
            const int trafo_width  =  ver_split_first ? (tu_width  / 2) : tu_width;
419
0
            const int trafo_height = !ver_split_first ? (tu_height / 2) : tu_height;
420
421
0
            #define TRANSFORM_TREE(x, y) do {                                           \
422
0
                ret = hls_transform_tree(lc, x, y, trafo_width, trafo_height, ch_type);  \
423
0
                if (ret < 0)                                                            \
424
0
                    return ret;                                                         \
425
0
            } while (0)
426
427
0
            TRANSFORM_TREE(x0, y0);
428
0
            if (ver_split_first)
429
0
                TRANSFORM_TREE(x0 + trafo_width, y0);
430
0
            else
431
0
                TRANSFORM_TREE(x0, y0 + trafo_height);
432
433
8.18M
        } else {
434
8.18M
            ret = hls_transform_unit(lc, x0, y0, tu_width, tu_height, 0, ch_type);
435
8.18M
            if (ret < 0)
436
2.03k
                return ret;
437
438
8.18M
        }
439
8.18M
    } else if (cu->sbt_flag) {
440
6.63k
        if (!cu->sbt_horizontal_flag) {
441
5.08k
            #define TRANSFORM_UNIT(x, width, idx) do {                              \
442
5.08k
                ret = hls_transform_unit(lc, x, y0, width, tu_height, idx, ch_type); \
443
5.08k
                if (ret < 0)                                                        \
444
5.08k
                    return ret;                                                     \
445
5.08k
            } while (0)
446
447
2.54k
            const int trafo_width = tu_width * lc->parse.sbt_num_fourths_tb0 / 4;
448
2.54k
            TRANSFORM_UNIT(x0, trafo_width, 0);
449
2.54k
            TRANSFORM_UNIT(x0 + trafo_width, tu_width - trafo_width, 1);
450
451
2.54k
            #undef TRANSFORM_UNIT
452
4.09k
        } else {
453
8.02k
            #define TRANSFORM_UNIT(y, height, idx) do {                             \
454
8.02k
                ret = hls_transform_unit(lc, x0, y, tu_width, height, idx, ch_type); \
455
8.02k
                if (ret < 0)                                                        \
456
8.02k
                    return ret;                                                     \
457
8.02k
            } while (0)
458
459
4.09k
            const int trafo_height = tu_height * lc->parse.sbt_num_fourths_tb0 / 4;
460
4.09k
            TRANSFORM_UNIT(y0, trafo_height, 0);
461
3.93k
            TRANSFORM_UNIT(y0 + trafo_height, tu_height - trafo_height, 1);
462
463
3.93k
            #undef TRANSFORM_UNIT
464
3.93k
        }
465
69.9k
    } else if (cu->isp_split_type == ISP_HOR_SPLIT) {
466
28.5k
        const int trafo_height = tu_height / cu->num_intra_subpartitions;
467
118k
        for (int i = 0; i < cu->num_intra_subpartitions; i++) {
468
90.4k
            ret = hls_transform_unit(lc, x0, y0 + trafo_height * i, tu_width, trafo_height, i, 0);
469
90.4k
            if (ret < 0)
470
75
                return ret;
471
90.4k
        }
472
41.3k
    } else if (cu->isp_split_type == ISP_VER_SPLIT) {
473
41.3k
        const int trafo_width = tu_width / cu->num_intra_subpartitions;
474
181k
        for (int i = 0; i < cu->num_intra_subpartitions; i++) {
475
140k
            ret = hls_transform_unit(lc, x0 + trafo_width * i , y0, trafo_width, tu_height, i, 0);
476
140k
            if (ret < 0)
477
37
                return ret;
478
140k
        }
479
41.3k
    }
480
481
8.25M
    return 0;
482
8.25M
}
483
484
static int skipped_transform_tree(VVCLocalContext *lc, int x0, int y0,int tu_width, int tu_height)
485
152k
{
486
152k
    VVCFrameContext *fc  = lc->fc;
487
152k
    const CodingUnit *cu = lc->cu;
488
152k
    const VVCSPS *sps    = fc->ps.sps;
489
490
152k
    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
152k
    } else {
507
152k
        TransformUnit *tu    = add_tu(fc, lc->cu, x0, y0, tu_width, tu_height);
508
152k
        int start, end;
509
510
152k
        if (!tu)
511
0
            return AVERROR_INVALIDDATA;
512
152k
        ff_vvc_channel_range(&start, &end, cu->tree_type, sps->r->sps_chroma_format_idc);
513
404k
        for (int i = start; i < end; i++) {
514
251k
            TransformBlock *tb = add_tb(tu, lc, x0, y0, tu_width >> sps->hshift[i], tu_height >> sps->vshift[i], i);
515
251k
            if (i != CR)
516
202k
                set_tb_size(fc, tb);
517
251k
        }
518
152k
    }
519
520
152k
    return 0;
521
152k
}
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
18.5M
{
530
18.5M
    int min_qt_size, max_bt_size, max_tt_size, max_mtt_depth;
531
18.5M
    const VVCFrameContext *fc   = lc->fc;
532
18.5M
    const VVCSH *sh             = &lc->sc->sh;
533
18.5M
    const VVCSPS *sps           = fc->ps.sps;
534
18.5M
    const VVCPPS *pps           = fc->ps.pps;
535
18.5M
    const int chroma            = tree_type == DUAL_TREE_CHROMA;
536
18.5M
    int min_cb_size_y           = sps->min_cb_size_y;
537
18.5M
    int *qt                     = &split->qt;
538
18.5M
    int *btv                    = &split->btv;
539
18.5M
    int *bth                    = &split->bth;
540
18.5M
    int *ttv                    = &split->ttv;
541
18.5M
    int *tth                    = &split->tth;
542
543
18.5M
    *qt = *bth = *btv = *tth = *ttv = 1;
544
545
18.5M
    if (mtt_depth)
546
5.00M
        *qt = 0;
547
548
18.5M
    min_qt_size = sh->min_qt_size[chroma];
549
18.5M
    if (cb_width <= min_qt_size)
550
7.02M
        *qt = 0;
551
552
18.5M
    if (chroma) {
553
5.43M
        int chroma_area = (cb_width >> sps->hshift[1]) * (cb_height >> sps->vshift[1]);
554
5.43M
        int chroma_width = cb_width >> sps->hshift[1];
555
556
5.43M
        if (chroma_width == 8)
557
1.14M
            *ttv = 0;
558
4.28M
        else if (chroma_width <= 4) {
559
1.20M
            if (chroma_width == 4)
560
1.20M
                *btv = 0;
561
1.20M
            *qt = 0;
562
1.20M
        }
563
5.43M
        if (mode_type == MODE_TYPE_INTRA)
564
315k
            *qt = *btv = *bth = *ttv = *tth = 0;
565
5.43M
        if (chroma_area <= 32) {
566
1.40M
            *ttv = *tth = 0;
567
1.40M
            if (chroma_area <= 16)
568
1.17M
                *btv = *bth = 0;
569
1.40M
        }
570
5.43M
    }
571
18.5M
    max_bt_size = sh->max_bt_size[chroma];
572
18.5M
    max_tt_size = sh->max_tt_size[chroma];
573
18.5M
    max_mtt_depth = sh->max_mtt_depth[chroma] + depth_offset;
574
575
18.5M
    if (mode_type == MODE_TYPE_INTER) {
576
26.0k
        int area = cb_width * cb_height;
577
26.0k
        if (area == 32)
578
26.0k
            *btv = *bth = 0;
579
0
        else if (area == 64)
580
0
            *ttv = *tth = 0;
581
26.0k
    }
582
18.5M
    if (cb_width <= 2 * min_cb_size_y) {
583
7.91M
        *ttv = 0;
584
7.91M
        if (cb_width <= min_cb_size_y)
585
4.08M
            *btv = 0;
586
7.91M
    }
587
18.5M
    if (cb_height <= 2 * min_cb_size_y) {
588
8.87M
        *tth = 0;
589
8.87M
        if (cb_height <= min_cb_size_y)
590
4.61M
            *bth = 0;
591
8.87M
    }
592
18.5M
    if (cb_width > max_bt_size || cb_height > max_bt_size)
593
8.23M
        *btv = *bth = 0;
594
18.5M
    max_tt_size = FFMIN(64, max_tt_size);
595
18.5M
    if (cb_width > max_tt_size || cb_height > max_tt_size)
596
8.32M
        *ttv = *tth = 0;
597
18.5M
    if (mtt_depth >= max_mtt_depth)
598
9.97M
        *btv = *bth = *ttv = *tth = 0;
599
18.5M
    if (x0 + cb_width > pps->width) {
600
6.99M
        *ttv = *tth = 0;
601
6.99M
        if (cb_height > 64)
602
16.7k
            *btv = 0;
603
6.99M
        if (y0 + cb_height <= pps->height)
604
476k
            *bth = 0;
605
6.51M
        else if (cb_width > min_qt_size)
606
5.88M
            *btv = *bth = 0;
607
6.99M
    }
608
18.5M
    if (y0 + cb_height > pps->height) {
609
6.68M
        *btv = *ttv = *tth = 0;
610
6.68M
        if (cb_width > 64)
611
16.7k
            *bth = 0;
612
6.68M
    }
613
18.5M
    if (mtt_depth > 0 && part_idx  == 1)  {
614
1.86M
        if (last_split_mode == SPLIT_TT_VER)
615
117k
            *btv = 0;
616
1.74M
        else if (last_split_mode == SPLIT_TT_HOR)
617
138k
            *bth = 0;
618
1.86M
    }
619
18.5M
    if (cb_width <= 64 && cb_height > 64)
620
0
        *btv = 0;
621
18.5M
    if (cb_width > 64 && cb_height <= 64)
622
0
        *bth = 0;
623
18.5M
}
624
625
static int get_num_intra_subpartitions(enum IspType isp_split_type, int cb_width, int cb_height)
626
4.76M
{
627
4.76M
    if (isp_split_type == ISP_NO_SPLIT)
628
4.69M
        return 1;
629
69.9k
    if ((cb_width == 4 && cb_height == 8) || (cb_width == 8 && cb_height == 4))
630
24.1k
        return 2;
631
45.7k
    return 4;
632
69.9k
}
633
634
static int get_cclm_enabled(const VVCLocalContext *lc, const int x0, const int y0)
635
3.09M
{
636
3.09M
    const VVCFrameContext *fc = lc->fc;
637
3.09M
    const VVCSPS *sps   = fc->ps.sps;
638
3.09M
    int enabled = 0;
639
640
3.09M
    if (!sps->r->sps_cclm_enabled_flag)
641
641k
        return 0;
642
2.45M
    if (!sps->r->sps_qtbtt_dual_tree_intra_flag || !IS_I(lc->sc->sh.r) || sps->ctb_log2_size_y < 6)
643
747k
        return 1;
644
1.70M
    else {
645
1.70M
        const int x64 = x0 >> 6 << 6;
646
1.70M
        const int y64 = y0 >> 6 << 6;
647
1.70M
        const int y32 = y0 >> 5 << 5;
648
1.70M
        const int x64_cu = x64 >> fc->ps.sps->min_cb_log2_size_y;
649
1.70M
        const int y64_cu = y64 >> fc->ps.sps->min_cb_log2_size_y;
650
1.70M
        const int y32_cu = y32 >> fc->ps.sps->min_cb_log2_size_y;
651
1.70M
        const int min_cb_width = fc->ps.pps->min_cb_width;
652
1.70M
        const int depth = SAMPLE_CTB(fc->tab.cqt_depth[1], x64_cu, y64_cu);
653
1.70M
        const int min_depth = fc->ps.sps->ctb_log2_size_y - 6;
654
1.70M
        const VVCSplitMode msm64 = (VVCSplitMode)TAB_MSM(fc, 0, x64, y64);
655
1.70M
        const VVCSplitMode msm32 = (VVCSplitMode)TAB_MSM(fc, 1, x64, y32);
656
657
1.70M
        enabled = SAMPLE_CTB(fc->tab.cb_width[1], x64_cu, y64_cu) == 64 &&
658
106k
            SAMPLE_CTB(fc->tab.cb_height[1], x64_cu, y64_cu) == 64;
659
1.70M
        enabled |= depth == min_depth && msm64 == SPLIT_BT_HOR &&
660
38.9k
            SAMPLE_CTB(fc->tab.cb_width[1], x64_cu, y32_cu) == 64 &&
661
26.3k
            SAMPLE_CTB(fc->tab.cb_height[1], x64_cu, y32_cu) == 32;
662
1.70M
        enabled |= depth > min_depth;
663
1.70M
        enabled |= depth == min_depth && msm64 == SPLIT_BT_HOR && msm32 == SPLIT_BT_VER;
664
665
1.70M
        if (enabled) {
666
1.66M
            const int w = SAMPLE_CTB(fc->tab.cb_width[0], x64_cu, y64_cu);
667
1.66M
            const int h = SAMPLE_CTB(fc->tab.cb_height[0], x64_cu, y64_cu);
668
1.66M
            const int depth0 = SAMPLE_CTB(fc->tab.cqt_depth[0], x64_cu, y64_cu);
669
1.66M
            if ((w == 64 && h == 64 && TAB_ISPMF(fc, x64, y64)) ||
670
1.65M
                ((w < 64 || h < 64) && depth0 == min_depth))
671
6.86k
                return 0;
672
1.66M
        }
673
674
1.70M
    }
675
676
1.69M
    return enabled;
677
2.45M
}
678
679
static int less(const void *a, const void *b)
680
8.15M
{
681
8.15M
    return *(const int*)a - *(const int*)b;
682
8.15M
}
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
4.76M
{
687
4.76M
    VVCFrameContext *fc     = lc->fc;
688
4.76M
    CodingUnit *cu          = lc->cu;
689
4.76M
    const int x0            = cu->x0;
690
4.76M
    const int y0            = cu->y0;
691
4.76M
    enum IntraPredMode pred;
692
4.76M
    int intra_luma_not_planar_flag = 1;
693
4.76M
    int intra_luma_mpm_remainder = 0;
694
4.76M
    int intra_luma_mpm_flag = 1;
695
4.76M
    int intra_luma_mpm_idx = 0;
696
697
4.76M
    if (!cu->intra_luma_ref_idx)
698
4.72M
        intra_luma_mpm_flag = ff_vvc_intra_luma_mpm_flag(lc);
699
4.76M
    if (intra_luma_mpm_flag) {
700
3.58M
        if (!cu->intra_luma_ref_idx)
701
3.55M
            intra_luma_not_planar_flag = ff_vvc_intra_luma_not_planar_flag(lc, intra_subpartitions_mode_flag);
702
3.58M
        if (intra_luma_not_planar_flag)
703
1.93M
            intra_luma_mpm_idx = ff_vvc_intra_luma_mpm_idx(lc);
704
3.58M
    } else {
705
1.17M
        intra_luma_mpm_remainder = ff_vvc_intra_luma_mpm_remainder(lc);
706
1.17M
    }
707
708
4.76M
    if (!intra_luma_not_planar_flag) {
709
1.64M
        pred = INTRA_PLANAR;
710
3.11M
    } else {
711
3.11M
        const VVCSPS *sps       = fc->ps.sps;
712
3.11M
        const int x_a           = (x0 - 1) >> sps->min_cb_log2_size_y;
713
3.11M
        const int y_a           = (y0 + cu->cb_height - 1) >> sps->min_cb_log2_size_y;
714
3.11M
        const int x_b           = (x0 + cu->cb_width - 1) >> sps->min_cb_log2_size_y;
715
3.11M
        const int y_b           = (y0 - 1) >> sps->min_cb_log2_size_y;
716
3.11M
        int min_cb_width        = fc->ps.pps->min_cb_width;
717
3.11M
        int x0b                 = av_zero_extend(x0, sps->ctb_log2_size_y);
718
3.11M
        int y0b                 = av_zero_extend(y0, sps->ctb_log2_size_y);
719
3.11M
        const int available_l   = lc->ctb_left_flag || x0b;
720
3.11M
        const int available_u   = lc->ctb_up_flag || y0b;
721
722
3.11M
        int a, b, cand[5];
723
724
3.11M
       if (!available_l || (SAMPLE_CTB(fc->tab.cpm[0], x_a, y_a) != MODE_INTRA) ||
725
1.72M
            SAMPLE_CTB(fc->tab.imf, x_a, y_a)) {
726
1.72M
            a = INTRA_PLANAR;
727
1.72M
        } else {
728
1.39M
            a = SAMPLE_CTB(fc->tab.ipm, x_a, y_a);
729
1.39M
        }
730
731
3.11M
        if (!available_u || (SAMPLE_CTB(fc->tab.cpm[0], x_b, y_b) != MODE_INTRA) ||
732
1.77M
            SAMPLE_CTB(fc->tab.imf, x_b, y_b) || !y0b) {
733
1.77M
            b = INTRA_PLANAR;
734
1.77M
        } else {
735
1.33M
            b = SAMPLE_CTB(fc->tab.ipm, x_b, y_b);
736
1.33M
        }
737
738
3.11M
        if (a == b && a > INTRA_DC) {
739
62.6k
            cand[0] = a;
740
62.6k
            cand[1] = 2 + ((a + 61) % 64);
741
62.6k
            cand[2] = 2 + ((a -  1) % 64);
742
62.6k
            cand[3] = 2 + ((a + 60) % 64);
743
62.6k
            cand[4] = 2 + (a % 64);
744
3.05M
        } else {
745
3.05M
            const int minab = FFMIN(a, b);
746
3.05M
            const int maxab = FFMAX(a, b);
747
3.05M
            if (a > INTRA_DC && b > INTRA_DC) {
748
286k
                const int diff = maxab - minab;
749
286k
                cand[0] = a;
750
286k
                cand[1] = b;
751
286k
                if (diff == 1) {
752
56.1k
                    cand[2] = 2 + ((minab + 61) % 64);
753
56.1k
                    cand[3] = 2 + ((maxab - 1) % 64);
754
56.1k
                    cand[4] = 2 + ((minab + 60) % 64);
755
230k
                } else if (diff >= 62) {
756
2.15k
                    cand[2] = 2 + ((minab - 1) % 64);
757
2.15k
                    cand[3] = 2 + ((maxab + 61) % 64);
758
2.15k
                    cand[4] = 2 + (minab % 64);
759
228k
                } else if (diff == 2) {
760
29.6k
                    cand[2] = 2 + ((minab - 1) % 64);
761
29.6k
                    cand[3] = 2 + ((minab + 61) % 64);
762
29.6k
                    cand[4] = 2 + ((maxab - 1) % 64);
763
198k
                } else {
764
198k
                    cand[2] = 2 + ((minab + 61) % 64);
765
198k
                    cand[3] = 2 + ((minab - 1) % 64);
766
198k
                    cand[4] = 2 + ((maxab + 61) % 64);
767
198k
                }
768
2.76M
            } else if (a > INTRA_DC || b > INTRA_DC) {
769
961k
                cand[0] = maxab;
770
961k
                cand[1] = 2 + ((maxab + 61 ) % 64);
771
961k
                cand[2] = 2 + ((maxab - 1) % 64);
772
961k
                cand[3] = 2 + ((maxab + 60 ) % 64);
773
961k
                cand[4] = 2 + (maxab % 64);
774
1.80M
            } else {
775
1.80M
                cand[0] = INTRA_DC;
776
1.80M
                cand[1] = INTRA_VERT;
777
1.80M
                cand[2] = INTRA_HORZ;
778
1.80M
                cand[3] = INTRA_VERT - 4;
779
1.80M
                cand[4] = INTRA_VERT + 4;
780
1.80M
            }
781
3.05M
        }
782
3.11M
        if (intra_luma_mpm_flag) {
783
1.93M
            pred = cand[intra_luma_mpm_idx];
784
1.93M
        } else {
785
1.17M
            qsort(cand, FF_ARRAY_ELEMS(cand), sizeof(cand[0]), less);
786
1.17M
            pred = intra_luma_mpm_remainder + 1;
787
7.07M
            for (int i = 0; i < FF_ARRAY_ELEMS(cand); i++) {
788
5.89M
                if (pred >= cand[i])
789
2.90M
                    pred++;
790
5.89M
            }
791
1.17M
        }
792
3.11M
    }
793
4.76M
    return pred;
794
4.76M
}
795
796
static int lfnst_idx_decode(VVCLocalContext *lc)
797
8.25M
{
798
8.25M
    CodingUnit  *cu             = lc->cu;
799
8.25M
    const VVCTreeType tree_type = cu->tree_type;
800
8.25M
    const VVCSPS *sps           = lc->fc->ps.sps;
801
8.25M
    const int cb_width          = cu->cb_width;
802
8.25M
    const int cb_height         = cu->cb_height;
803
8.25M
    const TransformUnit  *tu    = cu->tus.head;
804
8.25M
    int lfnst_width, lfnst_height, min_lfnst;
805
8.25M
    int lfnst_idx = 0;
806
807
8.25M
    memset(cu->apply_lfnst_flag, 0, sizeof(cu->apply_lfnst_flag));
808
809
8.25M
    if (!sps->r->sps_lfnst_enabled_flag || cu->pred_mode != MODE_INTRA || FFMAX(cb_width, cb_height) > sps->max_tb_size_y)
810
3.73M
        return 0;
811
812
8.83M
    while (tu) {
813
11.2M
        for (int j = 0; j < tu->nb_tbs; j++) {
814
6.91M
            const TransformBlock *tb = tu->tbs + j;
815
6.91M
            if (tu->coded_flag[tb->c_idx] && tb->ts)
816
271k
                return 0;
817
6.91M
        }
818
4.31M
        tu = tu->next;
819
4.31M
    }
820
821
4.25M
    if (tree_type == DUAL_TREE_CHROMA) {
822
1.71M
        lfnst_width  = cb_width  >> sps->hshift[1];
823
1.71M
        lfnst_height = cb_height >> sps->vshift[1];
824
2.54M
    } else {
825
2.54M
        const int vs = cu->isp_split_type == ISP_VER_SPLIT;
826
2.54M
        const int hs = cu->isp_split_type == ISP_HOR_SPLIT;
827
2.54M
        lfnst_width = vs ? cb_width / cu->num_intra_subpartitions : cb_width;
828
2.54M
        lfnst_height = hs ? cb_height / cu->num_intra_subpartitions : cb_height;
829
2.54M
    }
830
4.25M
    min_lfnst = FFMIN(lfnst_width, lfnst_height);
831
4.25M
    if (tree_type != DUAL_TREE_CHROMA && cu->intra_mip_flag && min_lfnst < 16)
832
133k
        return 0;
833
834
4.12M
    if (min_lfnst >= 4) {
835
4.03M
        if ((cu->isp_split_type != ISP_NO_SPLIT || !lc->parse.lfnst_dc_only) && lc->parse.lfnst_zero_out_sig_coeff_flag)
836
430k
            lfnst_idx = ff_vvc_lfnst_idx(lc, tree_type != SINGLE_TREE);
837
4.03M
    }
838
839
4.12M
    if (lfnst_idx) {
840
335k
        cu->apply_lfnst_flag[LUMA] = tree_type != DUAL_TREE_CHROMA;
841
335k
        cu->apply_lfnst_flag[CB] = cu->apply_lfnst_flag[CR] = tree_type == DUAL_TREE_CHROMA;
842
335k
    }
843
844
4.12M
    return lfnst_idx;
845
4.25M
}
846
847
static MtsIdx mts_idx_decode(VVCLocalContext *lc)
848
8.25M
{
849
8.25M
    const CodingUnit *cu    = lc->cu;
850
8.25M
    const VVCSPS     *sps   = lc->fc->ps.sps;
851
8.25M
    const int cb_width      = cu->cb_width;
852
8.25M
    const int cb_height     = cu->cb_height;
853
8.25M
    const uint8_t transform_skip_flag = cu->tus.head->tbs[0].ts; //fix me
854
8.25M
    int mts_idx = MTS_DCT2_DCT2;
855
8.25M
    if (cu->tree_type != DUAL_TREE_CHROMA && !cu->lfnst_idx &&
856
5.49M
        !transform_skip_flag && FFMAX(cb_width, cb_height) <= 32 &&
857
4.83M
        cu->isp_split_type == ISP_NO_SPLIT && !cu->sbt_flag &&
858
4.75M
        lc->parse.mts_zero_out_sig_coeff_flag && !lc->parse.mts_dc_only) {
859
3.53M
        if ((cu->pred_mode == MODE_INTER && sps->r->sps_explicit_mts_inter_enabled_flag) ||
860
3.52M
            (cu->pred_mode == MODE_INTRA && sps->r->sps_explicit_mts_intra_enabled_flag)) {
861
1.22M
            mts_idx = ff_vvc_mts_idx(lc);
862
1.22M
        }
863
3.53M
    }
864
865
8.25M
    return mts_idx;
866
8.25M
}
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.26M
{
870
3.26M
    const int x_center            = (cu->x0 + cu->cb_width / 2) >> sps->min_cb_log2_size_y;
871
3.26M
    const int y_center            = (cu->y0 + cu->cb_height / 2) >> sps->min_cb_log2_size_y;
872
3.26M
    const int min_cb_width        = pps->min_cb_width;
873
3.26M
    const int intra_mip_flag      = SAMPLE_CTB(fc->tab.imf, x_center, y_center);
874
3.26M
    const int cu_pred_mode        = SAMPLE_CTB(fc->tab.cpm[0], x_center, y_center);
875
3.26M
    const int intra_pred_mode_y   = SAMPLE_CTB(fc->tab.ipm, x_center, y_center);
876
877
3.26M
    if (intra_mip_flag) {
878
102k
        if (cu->tree_type == SINGLE_TREE && sps->r->sps_chroma_format_idc == CHROMA_FORMAT_444)
879
15.0k
            return INTRA_INVALID;
880
87.7k
        return INTRA_PLANAR;
881
102k
    }
882
3.16M
    if (cu_pred_mode == MODE_IBC || cu_pred_mode == MODE_PLT)
883
152k
        return INTRA_DC;
884
3.01M
    return intra_pred_mode_y;
885
3.16M
}
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.28M
{
890
3.28M
    const VVCFrameContext *fc   = lc->fc;
891
3.28M
    CodingUnit *cu              = lc->cu;
892
3.28M
    const VVCSPS *sps           = fc->ps.sps;
893
3.28M
    const VVCPPS *pps           = fc->ps.pps;
894
3.28M
    const int x_cb              = cu->x0 >> sps->min_cb_log2_size_y;
895
3.28M
    const int y_cb              = cu->y0 >> sps->min_cb_log2_size_y;
896
3.28M
    const int min_cb_width      = pps->min_cb_width;
897
3.28M
    const int intra_mip_flag    = SAMPLE_CTB(fc->tab.imf, x_cb, y_cb);
898
3.28M
    enum IntraPredMode luma_intra_pred_mode = SAMPLE_CTB(fc->tab.ipm, x_cb, y_cb);
899
900
3.28M
    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
19.0k
        cu->mip_chroma_direct_flag = 1;
903
19.0k
        cu->intra_pred_mode_c = luma_intra_pred_mode;
904
19.0k
        return;
905
19.0k
    }
906
3.26M
    luma_intra_pred_mode = derive_center_luma_intra_pred_mode(fc, sps, pps, cu);
907
908
3.26M
    if (cu->act_enabled_flag) {
909
190k
        cu->intra_pred_mode_c = luma_intra_pred_mode;
910
190k
        return;
911
190k
    }
912
3.07M
    if (cclm_mode_flag) {
913
1.65M
        cu->intra_pred_mode_c = INTRA_LT_CCLM + cclm_mode_idx;
914
1.65M
    } else if (intra_chroma_pred_mode == 4){
915
1.14M
        cu->intra_pred_mode_c = luma_intra_pred_mode;
916
1.14M
    } else {
917
277k
        const static IntraPredMode pred_mode_c[][4 + 1] = {
918
277k
            {INTRA_VDIAG, INTRA_PLANAR, INTRA_PLANAR, INTRA_PLANAR, INTRA_PLANAR},
919
277k
            {INTRA_VERT,  INTRA_VDIAG,  INTRA_VERT,   INTRA_VERT,   INTRA_VERT},
920
277k
            {INTRA_HORZ,  INTRA_HORZ,   INTRA_VDIAG,  INTRA_HORZ,   INTRA_HORZ},
921
277k
            {INTRA_DC,    INTRA_DC,     INTRA_DC,     INTRA_VDIAG,  INTRA_DC},
922
277k
        };
923
277k
        const int modes[4] = {INTRA_PLANAR, INTRA_VERT, INTRA_HORZ, INTRA_DC};
924
277k
        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
277k
        if (cu->tree_type == SINGLE_TREE && sps->r->sps_chroma_format_idc == CHROMA_FORMAT_444 && intra_mip_flag) {
930
1.57k
            idx = 4;
931
275k
        } else {
932
838k
            for (idx = 0; idx < FF_ARRAY_ELEMS(modes); idx++) {
933
774k
                if (modes[idx] == luma_intra_pred_mode)
934
211k
                    break;
935
774k
            }
936
275k
        }
937
938
277k
        cu->intra_pred_mode_c = pred_mode_c[intra_chroma_pred_mode][idx];
939
277k
    }
940
3.07M
    if (sps->r->sps_chroma_format_idc == CHROMA_FORMAT_422 && cu->intra_pred_mode_c <= INTRA_VDIAG) {
941
11.7k
        const static int mode_map_422[INTRA_VDIAG + 1] = {
942
11.7k
             0,  1, 61, 62, 63, 64, 65, 66,  2,  3,  5,  6,  8, 10, 12, 13,
943
11.7k
            14, 16, 18, 20, 22, 23, 24, 26, 28, 30, 31, 33, 34, 35, 36, 37,
944
11.7k
            38, 39, 40, 41, 41, 42, 43, 43, 44, 44, 45, 45, 46, 47, 48, 48,
945
11.7k
            49, 49, 50, 51, 51, 52, 52, 53, 54, 55, 55, 56, 56, 57, 57, 58,
946
11.7k
            59, 59, 60,
947
11.7k
        };
948
11.7k
        cu->intra_pred_mode_c = mode_map_422[cu->intra_pred_mode_c];
949
11.7k
    }
950
3.07M
}
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
374k
{
955
374k
    return (intra_mip_mode << 2) | (intra_mip_transposed_flag << 1) | intra_mip_flag;
956
374k
}
957
958
static void intra_luma_pred_modes(VVCLocalContext *lc)
959
5.41M
{
960
5.41M
    VVCFrameContext *fc             = lc->fc;
961
5.41M
    const VVCSPS *sps               = fc->ps.sps;
962
5.41M
    const VVCPPS *pps               = fc->ps.pps;
963
5.41M
    CodingUnit *cu                  = lc->cu;
964
5.41M
    const int log2_min_cb_size      = sps->min_cb_log2_size_y;
965
5.41M
    const int x0                    = cu->x0;
966
5.41M
    const int y0                    = cu->y0;
967
5.41M
    const int x_cb                  = x0 >> log2_min_cb_size;
968
5.41M
    const int y_cb                  = y0 >> log2_min_cb_size;
969
5.41M
    const int cb_width              = cu->cb_width;
970
5.41M
    const int cb_height             = cu->cb_height;
971
972
5.41M
    cu->intra_luma_ref_idx  = 0;
973
5.41M
    if (sps->r->sps_bdpcm_enabled_flag && cb_width <= sps->max_ts_size && cb_height <= sps->max_ts_size)
974
1.40M
        cu->bdpcm_flag[LUMA] = ff_vvc_intra_bdpcm_luma_flag(lc);
975
5.41M
    if (cu->bdpcm_flag[LUMA]) {
976
323k
        cu->intra_pred_mode_y = ff_vvc_intra_bdpcm_luma_dir_flag(lc) ? INTRA_VERT : INTRA_HORZ;
977
5.09M
    } else {
978
5.09M
        if (sps->r->sps_mip_enabled_flag)
979
2.31M
            cu->intra_mip_flag = ff_vvc_intra_mip_flag(lc, fc->tab.imf);
980
5.09M
        if (cu->intra_mip_flag) {
981
329k
            int intra_mip_transposed_flag = ff_vvc_intra_mip_transposed_flag(lc);
982
329k
            int intra_mip_mode = ff_vvc_intra_mip_mode(lc);
983
329k
            int x = y_cb * pps->min_cb_width + x_cb;
984
704k
            for (int y = 0; y < (cb_height>>log2_min_cb_size); y++) {
985
374k
                int width = cb_width>>log2_min_cb_size;
986
374k
                const uint8_t mip_info = pack_mip_info(cu->intra_mip_flag,
987
374k
                        intra_mip_transposed_flag, intra_mip_mode);
988
374k
                memset(&fc->tab.imf[x], mip_info, width);
989
374k
                x += pps->min_cb_width;
990
374k
            }
991
329k
            cu->intra_pred_mode_y = intra_mip_mode;
992
4.76M
        } else {
993
4.76M
            int intra_subpartitions_mode_flag = 0;
994
4.76M
            if (sps->r->sps_mrl_enabled_flag && ((y0 % sps->ctb_size_y) > 0))
995
1.20M
                cu->intra_luma_ref_idx = ff_vvc_intra_luma_ref_idx(lc);
996
4.76M
            if (sps->r->sps_isp_enabled_flag && !cu->intra_luma_ref_idx &&
997
2.99M
                (cb_width <= sps->max_tb_size_y && cb_height <= sps->max_tb_size_y) &&
998
2.99M
                (cb_width * cb_height > MIN_TU_SIZE * MIN_TU_SIZE) &&
999
1.30M
                !cu->act_enabled_flag)
1000
1.26M
                intra_subpartitions_mode_flag = ff_vvc_intra_subpartitions_mode_flag(lc);
1001
4.76M
            if (!(x0 & 63) && !(y0 & 63))
1002
1.36M
                TAB_ISPMF(fc, x0, y0) = intra_subpartitions_mode_flag;
1003
4.76M
            cu->isp_split_type = ff_vvc_isp_split_type(lc, intra_subpartitions_mode_flag);
1004
4.76M
            cu->num_intra_subpartitions = get_num_intra_subpartitions(cu->isp_split_type, cb_width, cb_height);
1005
4.76M
            cu->intra_pred_mode_y = luma_intra_pred_mode(lc, intra_subpartitions_mode_flag);
1006
4.76M
        }
1007
5.09M
    }
1008
5.41M
    set_cb_tab(lc, fc->tab.ipm, cu->intra_pred_mode_y);
1009
5.41M
}
1010
1011
static void intra_chroma_pred_modes(VVCLocalContext *lc)
1012
3.31M
{
1013
3.31M
    const VVCSPS *sps          = lc->fc->ps.sps;
1014
3.31M
    CodingUnit *cu             = lc->cu;
1015
3.31M
    const int hs               = sps->hshift[CHROMA];
1016
3.31M
    const int vs               = sps->vshift[CHROMA];
1017
3.31M
    int cclm_mode_flag         = 0;
1018
3.31M
    int cclm_mode_idx          = 0;
1019
3.31M
    int intra_chroma_pred_mode = 0;
1020
1021
3.31M
    if (!cu->act_enabled_flag) {
1022
3.11M
        cu->mip_chroma_direct_flag = 0;
1023
3.11M
        if (sps->r->sps_bdpcm_enabled_flag &&
1024
482k
            (cu->cb_width  >> hs) <= sps->max_ts_size &&
1025
430k
            (cu->cb_height >> vs) <= sps->max_ts_size) {
1026
430k
            cu->bdpcm_flag[CB] = cu->bdpcm_flag[CR] = ff_vvc_intra_bdpcm_chroma_flag(lc);
1027
430k
        }
1028
3.11M
        if (cu->bdpcm_flag[CHROMA]) {
1029
25.6k
            cu->intra_pred_mode_c = ff_vvc_intra_bdpcm_chroma_dir_flag(lc) ? INTRA_VERT : INTRA_HORZ;
1030
3.09M
        } else {
1031
3.09M
            const int cclm_enabled = get_cclm_enabled(lc, cu->x0, cu->y0);
1032
1033
3.09M
            if (cclm_enabled)
1034
2.40M
                cclm_mode_flag = ff_vvc_cclm_mode_flag(lc);
1035
1036
3.09M
            if (cclm_mode_flag)
1037
1.65M
                cclm_mode_idx = ff_vvc_cclm_mode_idx(lc);
1038
1.43M
            else
1039
1.43M
                intra_chroma_pred_mode = ff_vvc_intra_chroma_pred_mode(lc);
1040
3.09M
        }
1041
3.11M
    }
1042
1043
3.31M
    if (!cu->bdpcm_flag[CHROMA])
1044
3.28M
        derive_chroma_intra_pred_mode(lc, cclm_mode_flag, cclm_mode_idx, intra_chroma_pred_mode);
1045
3.31M
}
1046
1047
static PredMode pred_mode_decode(VVCLocalContext *lc,
1048
                                 const VVCTreeType tree_type,
1049
                                 const VVCModeType mode_type)
1050
8.52M
{
1051
8.52M
    const VVCFrameContext *fc       = lc->fc;
1052
8.52M
    CodingUnit *cu                  = lc->cu;
1053
8.52M
    const VVCSPS *sps               = fc->ps.sps;
1054
8.52M
    const H266RawSliceHeader *rsh   = lc->sc->sh.r;
1055
8.52M
    const int ch_type               = tree_type == DUAL_TREE_CHROMA ? 1 : 0;
1056
8.52M
    const int is_4x4                = cu->cb_width == 4 && cu->cb_height == 4;
1057
8.52M
    const int is_128                = cu->cb_width == 128 || cu->cb_height == 128;
1058
8.52M
    const int hs                    = sps->hshift[CHROMA];
1059
8.52M
    const int vs                    = sps->vshift[CHROMA];
1060
8.52M
    int pred_mode_flag;
1061
8.52M
    int pred_mode_ibc_flag;
1062
8.52M
    PredMode pred_mode;
1063
1064
8.52M
    cu->skip_flag = 0;
1065
8.52M
    if (!IS_I(rsh) || sps->r->sps_ibc_enabled_flag) {
1066
4.21M
        if (tree_type != DUAL_TREE_CHROMA &&
1067
3.37M
            ((!is_4x4 && mode_type != MODE_TYPE_INTRA) ||
1068
3.36M
            (sps->r->sps_ibc_enabled_flag && !is_128))) {
1069
3.36M
            cu->skip_flag = ff_vvc_cu_skip_flag(lc, fc->tab.skip);
1070
3.36M
        }
1071
1072
4.21M
        if (is_4x4 || mode_type == MODE_TYPE_INTRA || IS_I(rsh)) {
1073
4.12M
            pred_mode_flag = 1;
1074
4.12M
        } else if (mode_type == MODE_TYPE_INTER || cu->skip_flag) {
1075
32.7k
            pred_mode_flag = 0;
1076
53.4k
        } else  {
1077
53.4k
            pred_mode_flag = ff_vvc_pred_mode_flag(lc, ch_type);
1078
53.4k
        }
1079
4.21M
        pred_mode = pred_mode_flag ? MODE_INTRA : MODE_INTER;
1080
1081
4.21M
        if (((IS_I(rsh) && !cu->skip_flag) ||
1082
207k
            (!IS_I(rsh) && (pred_mode != MODE_INTRA ||
1083
88.0k
            ((is_4x4 || mode_type == MODE_TYPE_INTRA) && !cu->skip_flag)))) &&
1084
4.16M
            !is_128 && mode_type != MODE_TYPE_INTER && sps->r->sps_ibc_enabled_flag &&
1085
4.11M
            tree_type != DUAL_TREE_CHROMA) {
1086
3.27M
            pred_mode_ibc_flag = ff_vvc_pred_mode_ibc_flag(lc, ch_type);
1087
3.27M
        } else if (cu->skip_flag && (is_4x4 || mode_type == MODE_TYPE_INTRA)) {
1088
36.5k
            pred_mode_ibc_flag = 1;
1089
895k
        } else if (is_128 || mode_type == MODE_TYPE_INTER || tree_type == DUAL_TREE_CHROMA) {
1090
864k
            pred_mode_ibc_flag = 0;
1091
864k
        } else {
1092
30.3k
            pred_mode_ibc_flag = (IS_I(rsh)) ? sps->r->sps_ibc_enabled_flag : 0;
1093
30.3k
        }
1094
4.21M
        if (pred_mode_ibc_flag)
1095
374k
            pred_mode = MODE_IBC;
1096
4.31M
    } else {
1097
4.31M
        pred_mode = MODE_INTRA;
1098
4.31M
    }
1099
1100
8.52M
    if (pred_mode == MODE_INTRA && sps->r->sps_palette_enabled_flag && !is_128 && !cu->skip_flag &&
1101
2.30M
        mode_type != MODE_TYPE_INTER && ((cu->cb_width * cu->cb_height) >
1102
2.30M
            (tree_type != DUAL_TREE_CHROMA ? 16 : (16 << hs << vs))) &&
1103
740k
        (mode_type != MODE_TYPE_INTRA || tree_type != DUAL_TREE_CHROMA)) {
1104
739k
        if (ff_vvc_pred_mode_plt_flag(lc))
1105
88.4k
            pred_mode = MODE_PLT;
1106
739k
    }
1107
1108
8.52M
    set_cb_tab(lc, fc->tab.cpm[cu->ch_type], pred_mode);
1109
8.52M
    if (tree_type == SINGLE_TREE)
1110
911k
        set_cb_tab(lc, fc->tab.cpm[CHROMA], pred_mode);
1111
1112
8.52M
    return pred_mode;
1113
8.52M
}
1114
1115
static void sbt_info(VVCLocalContext *lc, const VVCSPS *sps)
1116
8.25M
{
1117
8.25M
    CodingUnit *cu      = lc->cu;
1118
8.25M
    const int cb_width  = cu->cb_width;
1119
8.25M
    const int cb_height = cu->cb_height;
1120
1121
8.25M
    if (cu->pred_mode == MODE_INTER && sps->r->sps_sbt_enabled_flag && !cu->ciip_flag
1122
22.6k
        && cb_width <= sps->max_tb_size_y && cb_height <= sps->max_tb_size_y) {
1123
22.6k
        const int sbt_ver_h = cb_width  >= 8;
1124
22.6k
        const int sbt_hor_h = cb_height >= 8;
1125
22.6k
        cu->sbt_flag = 0;
1126
22.6k
        if (sbt_ver_h || sbt_hor_h)
1127
22.6k
            cu->sbt_flag = ff_vvc_sbt_flag(lc);
1128
22.6k
        if (cu->sbt_flag) {
1129
6.63k
            const int sbt_ver_q = cb_width  >= 16;
1130
6.63k
            const int sbt_hor_q = cb_height >= 16;
1131
6.63k
            int cu_sbt_quad_flag = 0;
1132
1133
6.63k
            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.63k
            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.63k
            } else {
1140
6.63k
                cu->sbt_horizontal_flag = sbt_hor_h;
1141
6.63k
                if (sbt_ver_h && sbt_hor_h)
1142
5.61k
                    cu->sbt_horizontal_flag = ff_vvc_sbt_horizontal_flag(lc);
1143
6.63k
            }
1144
6.63k
            cu->sbt_pos_flag = ff_vvc_sbt_pos_flag(lc);
1145
1146
6.63k
            {
1147
6.63k
                const int sbt_min = cu_sbt_quad_flag ? 1 : 2;
1148
6.63k
                lc->parse.sbt_num_fourths_tb0 = cu->sbt_pos_flag ? (4 - sbt_min) : sbt_min;
1149
6.63k
            }
1150
6.63k
        }
1151
22.6k
    }
1152
8.25M
}
1153
1154
static int skipped_transform_tree_unit(VVCLocalContext *lc)
1155
152k
{
1156
152k
    const H266RawSPS *rsps = lc->fc->ps.sps->r;
1157
152k
    const CodingUnit *cu   = lc->cu;
1158
152k
    int ret;
1159
1160
152k
    if (cu->tree_type != DUAL_TREE_CHROMA) {
1161
152k
        ret = set_qp_y(lc, cu->x0, cu->y0, 0);
1162
152k
        if (ret < 0)
1163
0
            return ret;
1164
152k
    }
1165
152k
    if (rsps->sps_chroma_format_idc && cu->tree_type != DUAL_TREE_LUMA)
1166
49.4k
        set_qp_c(lc);
1167
152k
    ret = skipped_transform_tree(lc, cu->x0, cu->y0, cu->cb_width, cu->cb_height);
1168
152k
    if (ret < 0)
1169
0
        return ret;
1170
152k
    return 0;
1171
152k
}
1172
1173
static void set_cb_pos(const VVCFrameContext *fc, const CodingUnit *cu)
1174
8.52M
{
1175
8.52M
    const VVCSPS *sps           = fc->ps.sps;
1176
8.52M
    const VVCPPS *pps           = fc->ps.pps;
1177
8.52M
    const int log2_min_cb_size  = sps->min_cb_log2_size_y;
1178
8.52M
    const int x_cb              = cu->x0 >> log2_min_cb_size;
1179
8.52M
    const int y_cb              = cu->y0 >> log2_min_cb_size;
1180
8.52M
    const int ch_type           = cu->ch_type;
1181
8.52M
    int x, y;
1182
1183
8.52M
    x = y_cb * pps->min_cb_width + x_cb;
1184
32.3M
    for (y = 0; y < (cu->cb_height >> log2_min_cb_size); y++) {
1185
23.8M
        const int width = cu->cb_width >> log2_min_cb_size;
1186
1187
178M
        for (int i = 0; i < width; i++) {
1188
154M
            fc->tab.cb_pos_x[ch_type][x + i] = cu->x0;
1189
154M
            fc->tab.cb_pos_y[ch_type][x + i] = cu->y0;
1190
154M
        }
1191
23.8M
        memset(&fc->tab.cb_width[ch_type][x], cu->cb_width, width);
1192
23.8M
        memset(&fc->tab.cb_height[ch_type][x], cu->cb_height, width);
1193
23.8M
        memset(&fc->tab.cqt_depth[ch_type][x], cu->cqt_depth, width);
1194
1195
23.8M
        x += pps->min_cb_width;
1196
23.8M
    }
1197
8.52M
}
1198
1199
static CodingUnit* alloc_cu(VVCLocalContext *lc, const int x0, const int y0)
1200
8.52M
{
1201
8.52M
    VVCFrameContext *fc = lc->fc;
1202
8.52M
    const VVCSPS *sps   = fc->ps.sps;
1203
8.52M
    const VVCPPS *pps   = fc->ps.pps;
1204
8.52M
    const int rx        = x0 >> sps->ctb_log2_size_y;
1205
8.52M
    const int ry        = y0 >> sps->ctb_log2_size_y;
1206
8.52M
    CodingUnit **cus    = fc->tab.cus + ry * pps->ctb_width + rx;
1207
8.52M
    CodingUnit *cu      = av_refstruct_pool_get(fc->cu_pool);
1208
1209
8.52M
    if (!cu)
1210
0
        return NULL;
1211
8.52M
    cu->next = NULL;
1212
1213
8.52M
    if (lc->cu)
1214
6.91M
        lc->cu->next = cu;
1215
1.61M
    else
1216
1.61M
        *cus = cu;
1217
8.52M
    lc->cu = cu;
1218
1219
8.52M
    return cu;
1220
8.52M
}
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
8.52M
{
1225
8.52M
    VVCFrameContext *fc = lc->fc;
1226
8.52M
    const int ch_type   = tree_type == DUAL_TREE_CHROMA ? 1 : 0;
1227
8.52M
    CodingUnit *cu      = alloc_cu(lc, x0, y0);
1228
1229
8.52M
    if (!cu)
1230
0
        return NULL;
1231
1232
8.52M
    memset(&cu->pu, 0, sizeof(cu->pu));
1233
1234
8.52M
    lc->parse.prev_tu_cbf_y = 0;
1235
1236
8.52M
    cu->sbt_flag = 0;
1237
8.52M
    cu->act_enabled_flag = 0;
1238
1239
8.52M
    cu->tree_type = tree_type;
1240
8.52M
    cu->x0 = x0;
1241
8.52M
    cu->y0 = y0;
1242
8.52M
    cu->cb_width = cb_width;
1243
8.52M
    cu->cb_height = cb_height;
1244
8.52M
    cu->ch_type = ch_type;
1245
8.52M
    cu->cqt_depth = cqt_depth;
1246
8.52M
    cu->tus.head = cu->tus.tail = NULL;
1247
8.52M
    cu->bdpcm_flag[LUMA] = cu->bdpcm_flag[CB] = cu->bdpcm_flag[CR] = 0;
1248
8.52M
    cu->isp_split_type = ISP_NO_SPLIT;
1249
8.52M
    cu->intra_mip_flag = 0;
1250
8.52M
    cu->ciip_flag = 0;
1251
8.52M
    cu->coded_flag = 1;
1252
8.52M
    cu->num_intra_subpartitions = 1;
1253
8.52M
    cu->pu.dmvr_flag = 0;
1254
1255
8.52M
    set_cb_pos(fc, cu);
1256
8.52M
    return cu;
1257
8.52M
}
1258
1259
static void set_cu_tabs(const VVCLocalContext *lc, const CodingUnit *cu)
1260
8.48M
{
1261
8.48M
    const VVCFrameContext *fc = lc->fc;
1262
8.48M
    const PredictionUnit *pu  = &cu->pu;
1263
8.48M
    const TransformUnit *tu   = cu->tus.head;
1264
1265
8.48M
    set_cb_tab(lc, fc->tab.mmi, pu->mi.motion_model_idc);
1266
8.48M
    set_cb_tab(lc, fc->tab.msf, pu->merge_subblock_flag);
1267
8.48M
    if (cu->tree_type != DUAL_TREE_CHROMA) {
1268
5.86M
        set_cb_tab(lc, fc->tab.skip, cu->skip_flag);
1269
5.86M
        set_cb_tab(lc, fc->tab.pcmf[LUMA], cu->bdpcm_flag[LUMA]);
1270
5.86M
    }
1271
8.48M
    if (cu->tree_type != DUAL_TREE_LUMA)
1272
3.52M
        set_cb_tab(lc, fc->tab.pcmf[CHROMA], cu->bdpcm_flag[CHROMA]);
1273
1274
17.1M
    while (tu) {
1275
21.7M
          for (int j = 0; j < tu->nb_tbs; j++) {
1276
13.0M
            const TransformBlock *tb = tu->tbs + j;
1277
13.0M
            if (tb->c_idx != LUMA)
1278
7.02M
                set_qp_c_tab(lc, tu, tb);
1279
13.0M
        }
1280
8.65M
        tu = tu->next;
1281
8.65M
    }
1282
8.48M
}
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.0k
{
1287
19.0k
    const SliceContext *sc  = lc->sc;
1288
19.0k
    Mv mmvd[2];
1289
1290
19.0k
    if (mvf->pred_flag == PF_BI) {
1291
14.1k
        const RefPicList *rpl = sc->rpl;
1292
14.1k
        const int poc = lc->fc->ps.ph.poc;
1293
14.1k
        const int diff[] = {
1294
14.1k
            poc - rpl[L0].refs[mvf->ref_idx[L0]].poc,
1295
14.1k
            poc - rpl[L1].refs[mvf->ref_idx[L1]].poc
1296
14.1k
        };
1297
14.1k
        const int sign = FFSIGN(diff[0]) != FFSIGN(diff[1]);
1298
1299
14.1k
        if (diff[0] == diff[1]) {
1300
4.18k
            mmvd[1] = mmvd[0] = *mmvd_offset;
1301
4.18k
        }
1302
9.98k
        else {
1303
9.98k
            const int i = FFABS(diff[0]) < FFABS(diff[1]);
1304
9.98k
            const int o = !i;
1305
9.98k
            mmvd[i] = *mmvd_offset;
1306
9.98k
            if (!rpl[L0].refs[mvf->ref_idx[L0]].is_lt && !rpl[L1].refs[mvf->ref_idx[L1]].is_lt) {
1307
4.40k
                ff_vvc_mv_scale(&mmvd[o], mmvd_offset, diff[i], diff[o]);
1308
4.40k
            }
1309
5.57k
            else {
1310
5.57k
                mmvd[o].x = sign ? -mmvd[i].x : mmvd[i].x;
1311
5.57k
                mmvd[o].y = sign ? -mmvd[i].y : mmvd[i].y;
1312
5.57k
            }
1313
9.98k
        }
1314
14.1k
        mvf->mv[0].x += mmvd[0].x;
1315
14.1k
        mvf->mv[0].y += mmvd[0].y;
1316
14.1k
        mvf->mv[1].x += mmvd[1].x;
1317
14.1k
        mvf->mv[1].y += mmvd[1].y;
1318
14.1k
    } else {
1319
4.85k
        const int idx = mvf->pred_flag - PF_L0;
1320
4.85k
        mvf->mv[idx].x += mmvd_offset->x;
1321
4.85k
        mvf->mv[idx].y += mmvd_offset->y;
1322
4.85k
    }
1323
1324
19.0k
}
1325
1326
static void mvf_to_mi(const MvField *mvf, MotionInfo *mi)
1327
41.3k
{
1328
41.3k
    mi->pred_flag = mvf->pred_flag;
1329
41.3k
    mi->bcw_idx = mvf->bcw_idx;
1330
41.3k
    mi->hpel_if_idx = mvf->hpel_if_idx;
1331
123k
    for (int i = 0; i < 2; i++) {
1332
82.6k
        const PredFlag mask = i + 1;
1333
82.6k
        if (mvf->pred_flag & mask) {
1334
68.7k
            mi->mv[i][0] = mvf->mv[i];
1335
68.7k
            mi->ref_idx[i] = mvf->ref_idx[i];
1336
68.7k
        }
1337
82.6k
    }
1338
41.3k
}
1339
1340
static void mv_merge_refine_pred_flag(MvField *mvf, const int width, const int height)
1341
41.3k
{
1342
41.3k
    if (mvf->pred_flag == PF_BI && (width + height) == 12) {
1343
6.81k
        mvf->pred_flag = PF_L0;
1344
6.81k
        mvf->bcw_idx = 0;
1345
6.81k
    }
1346
41.3k
}
1347
1348
// subblock-based inter prediction data
1349
static void merge_data_subblock(VVCLocalContext *lc)
1350
4.07k
{
1351
4.07k
    const VVCFrameContext *fc   = lc->fc;
1352
4.07k
    const VVCPH  *ph            = &fc->ps.ph;
1353
4.07k
    CodingUnit* cu              = lc->cu;
1354
4.07k
    PredictionUnit *pu          = &cu->pu;
1355
4.07k
    int merge_subblock_idx      = 0;
1356
1357
4.07k
    if (ph->max_num_subblock_merge_cand > 1) {
1358
3.81k
        merge_subblock_idx = ff_vvc_merge_subblock_idx(lc, ph->max_num_subblock_merge_cand);
1359
3.81k
    }
1360
4.07k
    ff_vvc_sb_mv_merge_mode(lc, merge_subblock_idx, pu);
1361
4.07k
}
1362
1363
static void merge_data_regular(VVCLocalContext *lc)
1364
39.3k
{
1365
39.3k
    const VVCFrameContext *fc   = lc->fc;
1366
39.3k
    const VVCSPS *sps           = fc->ps.sps;
1367
39.3k
    const VVCPH  *ph            = &fc->ps.ph;
1368
39.3k
    const CodingUnit* cu        = lc->cu;
1369
39.3k
    PredictionUnit *pu          = &lc->cu->pu;
1370
39.3k
    int merge_idx               = 0;
1371
39.3k
    Mv mmvd_offset;
1372
39.3k
    MvField mvf;
1373
1374
39.3k
    if (sps->r->sps_mmvd_enabled_flag)
1375
38.2k
        pu->mmvd_merge_flag = ff_vvc_mmvd_merge_flag(lc);
1376
39.3k
    if (pu->mmvd_merge_flag) {
1377
19.0k
        int mmvd_cand_flag = 0;
1378
19.0k
        if (sps->max_num_merge_cand > 1)
1379
18.5k
            mmvd_cand_flag = ff_vvc_mmvd_cand_flag(lc);
1380
19.0k
        ff_vvc_mmvd_offset_coding(lc, &mmvd_offset, ph->r->ph_mmvd_fullpel_only_flag);
1381
19.0k
        merge_idx = mmvd_cand_flag;
1382
20.2k
    } else if (sps->max_num_merge_cand > 1) {
1383
19.4k
        merge_idx = ff_vvc_merge_idx(lc);
1384
19.4k
    }
1385
39.3k
    ff_vvc_luma_mv_merge_mode(lc, merge_idx, 0, &mvf);
1386
39.3k
    if (pu->mmvd_merge_flag)
1387
19.0k
        derive_mmvd(lc, &mvf, &mmvd_offset);
1388
39.3k
    mv_merge_refine_pred_flag(&mvf, cu->cb_width, cu->cb_height);
1389
39.3k
    ff_vvc_store_mvf(lc, &mvf);
1390
39.3k
    mvf_to_mi(&mvf, &pu->mi);
1391
39.3k
}
1392
1393
static int ciip_flag_decode(VVCLocalContext *lc, const int ciip_avaiable, const int gpm_avaiable, const int is_128)
1394
10.2k
{
1395
10.2k
    const VVCFrameContext *fc   = lc->fc;
1396
10.2k
    const VVCSPS *sps           = fc->ps.sps;
1397
10.2k
    const CodingUnit *cu        = lc->cu;
1398
1399
10.2k
    if (ciip_avaiable && gpm_avaiable)
1400
4.70k
        return ff_vvc_ciip_flag(lc);
1401
5.59k
    return sps->r->sps_ciip_enabled_flag && !cu->skip_flag &&
1402
1.16k
            !is_128 && (cu->cb_width * cu->cb_height >= 64);
1403
10.2k
}
1404
1405
static void merge_data_gpm(VVCLocalContext *lc)
1406
8.26k
{
1407
8.26k
    const VVCFrameContext *fc   = lc->fc;
1408
8.26k
    const VVCSPS *sps           = fc->ps.sps;
1409
8.26k
    PredictionUnit *pu          = &lc->cu->pu;
1410
8.26k
    int merge_gpm_idx[2];
1411
1412
8.26k
    pu->merge_gpm_flag = 1;
1413
8.26k
    pu->gpm_partition_idx = ff_vvc_merge_gpm_partition_idx(lc);
1414
8.26k
    merge_gpm_idx[0] = ff_vvc_merge_gpm_idx(lc, 0);
1415
8.26k
    merge_gpm_idx[1] = 0;
1416
8.26k
    if (sps->max_num_gpm_merge_cand > 2)
1417
6.62k
        merge_gpm_idx[1] = ff_vvc_merge_gpm_idx(lc, 1);
1418
1419
8.26k
    ff_vvc_luma_mv_merge_gpm(lc, merge_gpm_idx, pu->gpm_mv);
1420
8.26k
    ff_vvc_store_gpm_mvf(lc, pu);
1421
8.26k
}
1422
1423
static void merge_data_ciip(VVCLocalContext *lc)
1424
2.02k
{
1425
2.02k
    const VVCFrameContext* fc   = lc->fc;
1426
2.02k
    const VVCSPS* sps           = fc->ps.sps;
1427
2.02k
    CodingUnit *cu              = lc->cu;
1428
2.02k
    MotionInfo *mi              = &cu->pu.mi;
1429
2.02k
    int merge_idx               = 0;
1430
2.02k
    MvField mvf;
1431
1432
2.02k
    if (sps->max_num_merge_cand > 1)
1433
1.79k
        merge_idx = ff_vvc_merge_idx(lc);
1434
2.02k
    ff_vvc_luma_mv_merge_mode(lc, merge_idx, 1, &mvf);
1435
2.02k
    mv_merge_refine_pred_flag(&mvf, cu->cb_width, cu->cb_height);
1436
2.02k
    ff_vvc_store_mvf(lc, &mvf);
1437
2.02k
    mvf_to_mi(&mvf, mi);
1438
2.02k
    cu->intra_pred_mode_y   = cu->intra_pred_mode_c = INTRA_PLANAR;
1439
2.02k
    cu->intra_luma_ref_idx  = 0;
1440
2.02k
    cu->intra_mip_flag      = 0;
1441
2.02k
}
1442
1443
// block-based inter prediction data
1444
static void merge_data_block(VVCLocalContext *lc)
1445
49.5k
{
1446
49.5k
    const VVCFrameContext* fc       = lc->fc;
1447
49.5k
    const VVCSPS *sps               = fc->ps.sps;
1448
49.5k
    const H266RawSliceHeader *rsh   = lc->sc->sh.r;
1449
49.5k
    CodingUnit *cu                  = lc->cu;
1450
49.5k
    const int cb_width              = cu->cb_width;
1451
49.5k
    const int cb_height             = cu->cb_height;
1452
49.5k
    const int is_128                = cb_width == 128 || cb_height == 128;
1453
49.5k
    const int ciip_avaiable         = sps->r->sps_ciip_enabled_flag &&
1454
29.1k
        !cu->skip_flag && (cb_width * cb_height >= 64);
1455
49.5k
    const int gpm_avaiable          = sps->r->sps_gpm_enabled_flag && IS_B(rsh) &&
1456
36.4k
        (cb_width >= 8) && (cb_height >=8) &&
1457
28.6k
        (cb_width < 8 * cb_height) && (cb_height < 8 *cb_width);
1458
1459
49.5k
    int regular_merge_flag = 1;
1460
1461
49.5k
    if (!is_128 && (ciip_avaiable || gpm_avaiable))
1462
31.4k
        regular_merge_flag = ff_vvc_regular_merge_flag(lc, cu->skip_flag);
1463
49.5k
    if (regular_merge_flag) {
1464
39.3k
        merge_data_regular(lc);
1465
39.3k
    } else {
1466
10.2k
        cu->ciip_flag = ciip_flag_decode(lc, ciip_avaiable, gpm_avaiable, is_128);
1467
10.2k
        if (cu->ciip_flag)
1468
2.02k
            merge_data_ciip(lc);
1469
8.26k
        else
1470
8.26k
            merge_data_gpm(lc);
1471
10.2k
    }
1472
49.5k
}
1473
1474
static int merge_data_ibc(VVCLocalContext *lc)
1475
116k
{
1476
116k
    const VVCFrameContext* fc = lc->fc;
1477
116k
    const VVCSPS* sps         = fc->ps.sps;
1478
116k
    MotionInfo *mi            = &lc->cu->pu.mi;
1479
116k
    int merge_idx             = 0;
1480
116k
    int ret;
1481
1482
116k
    mi->pred_flag = PF_IBC;
1483
1484
116k
    if (sps->max_num_ibc_merge_cand > 1)
1485
116k
        merge_idx = ff_vvc_merge_idx(lc);
1486
1487
116k
    ret = ff_vvc_luma_mv_merge_ibc(lc, merge_idx, &mi->mv[L0][0]);
1488
116k
    if (ret)
1489
86
        return ret;
1490
116k
    ff_vvc_store_mv(lc, mi);
1491
1492
116k
    return 0;
1493
116k
}
1494
1495
static int hls_merge_data(VVCLocalContext *lc)
1496
170k
{
1497
170k
    const VVCFrameContext *fc   = lc->fc;
1498
170k
    const VVCPH  *ph            = &fc->ps.ph;
1499
170k
    const CodingUnit *cu        = lc->cu;
1500
170k
    PredictionUnit *pu          = &lc->cu->pu;
1501
170k
    int ret;
1502
1503
170k
    pu->merge_gpm_flag = 0;
1504
170k
    pu->mi.num_sb_x = pu->mi.num_sb_y = 1;
1505
170k
    if (cu->pred_mode == MODE_IBC) {
1506
116k
        ret = merge_data_ibc(lc);
1507
116k
        if (ret)
1508
86
            return ret;
1509
116k
    } else {
1510
53.6k
        if (ph->max_num_subblock_merge_cand > 0 && cu->cb_width >= 8 && cu->cb_height >= 8)
1511
21.7k
            pu->merge_subblock_flag = ff_vvc_merge_subblock_flag(lc);
1512
53.6k
        if (pu->merge_subblock_flag)
1513
4.07k
            merge_data_subblock(lc);
1514
49.5k
        else
1515
49.5k
            merge_data_block(lc);
1516
53.6k
    }
1517
170k
    return 0;
1518
170k
}
1519
1520
static void hls_mvd_coding(VVCLocalContext *lc, Mv* mvd)
1521
290k
{
1522
290k
    int32_t mv[2];
1523
1524
871k
    for (int i = 0; i < 2; i++) {
1525
581k
        mv[i] = ff_vvc_abs_mvd_greater0_flag(lc);
1526
581k
    }
1527
1528
871k
    for (int i = 0; i < 2; i++) {
1529
581k
        if (mv[i])
1530
410k
            mv[i] += ff_vvc_abs_mvd_greater1_flag(lc);
1531
581k
    }
1532
1533
871k
    for (int i = 0; i < 2; i++) {
1534
581k
        if (mv[i] > 0) {
1535
410k
            if (mv[i] == 2)
1536
317k
                mv[i] += ff_vvc_abs_mvd_minus2(lc);
1537
410k
            mv[i] = (1 - 2 * ff_vvc_mvd_sign_flag(lc)) * mv[i];
1538
410k
        }
1539
581k
    }
1540
290k
    mvd->x = mv[0];
1541
290k
    mvd->y = mv[1];
1542
290k
}
1543
1544
static int bcw_idx_decode(VVCLocalContext *lc, const MotionInfo *mi, const int cb_width, const int cb_height)
1545
31.8k
{
1546
31.8k
    const VVCFrameContext *fc   = lc->fc;
1547
31.8k
    const VVCSPS *sps           = fc->ps.sps;
1548
31.8k
    const VVCPPS *pps           = fc->ps.pps;
1549
31.8k
    const VVCPH  *ph            = &fc->ps.ph;
1550
31.8k
    const VVCSH *sh             = &lc->sc->sh;
1551
31.8k
    const PredWeightTable *w    = pps->r->pps_wp_info_in_ph_flag ? &ph->pwt : &sh->pwt;
1552
31.8k
    int bcw_idx                 = 0;
1553
1554
31.8k
    if (sps->r->sps_bcw_enabled_flag && mi->pred_flag == PF_BI &&
1555
590
        !w->weight_flag[L0][LUMA][mi->ref_idx[0]] &&
1556
414
        !w->weight_flag[L1][LUMA][mi->ref_idx[1]] &&
1557
409
        !w->weight_flag[L0][CHROMA][mi->ref_idx[0]] &&
1558
312
        !w->weight_flag[L1][CHROMA][mi->ref_idx[1]] &&
1559
290
        cb_width * cb_height >= 256) {
1560
0
        bcw_idx = ff_vvc_bcw_idx(lc, ff_vvc_no_backward_pred_flag(lc));
1561
0
    }
1562
31.8k
    return bcw_idx;
1563
31.8k
}
1564
1565
static int8_t ref_idx_decode(VVCLocalContext *lc, const VVCSH *sh, const int sym_mvd_flag, const int lx)
1566
33.6k
{
1567
33.6k
    const H266RawSliceHeader *rsh   = sh->r;
1568
33.6k
    int ref_idx                     = 0;
1569
1570
33.6k
    if (rsh->num_ref_idx_active[lx] > 1 && !sym_mvd_flag)
1571
1.01k
        ref_idx = ff_vvc_ref_idx_lx(lc, rsh->num_ref_idx_active[lx]);
1572
32.6k
    else if (sym_mvd_flag)
1573
332
        ref_idx = sh->ref_idx_sym[lx];
1574
33.6k
    return ref_idx;
1575
33.6k
}
1576
1577
static int mvds_decode(VVCLocalContext *lc, Mv mvds[2][MAX_CONTROL_POINTS],
1578
    const int num_cp_mv, const int lx)
1579
33.6k
{
1580
33.6k
    const VVCFrameContext *fc   = lc->fc;
1581
33.6k
    const VVCPH *ph             = &fc->ps.ph;
1582
33.6k
    const PredictionUnit *pu    = &lc->cu->pu;
1583
33.6k
    const MotionInfo *mi        = &pu->mi;
1584
33.6k
    int has_no_zero_mvd         = 0;
1585
1586
33.6k
    if (lx == L1 && ph->r->ph_mvd_l1_zero_flag && mi->pred_flag == PF_BI) {
1587
1.09k
        for (int j = 0; j < num_cp_mv; j++)
1588
546
            AV_ZERO64(&mvds[lx][j]);
1589
33.0k
    } else {
1590
33.0k
        Mv *mvd0 = &mvds[lx][0];
1591
33.0k
        if (lx == L1 && pu->sym_mvd_flag) {
1592
166
            mvd0->x = -mvds[L0][0].x;
1593
166
            mvd0->y = -mvds[L0][0].y;
1594
32.9k
        } else {
1595
32.9k
            hls_mvd_coding(lc, mvd0);
1596
32.9k
        }
1597
33.0k
        has_no_zero_mvd |= (mvd0->x || mvd0->y);
1598
33.0k
        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
33.0k
    }
1606
33.6k
    return has_no_zero_mvd;
1607
33.6k
}
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
31.8k
{
1612
95.5k
    for (int i = 0; i < 2; i++) {
1613
63.7k
        const PredFlag mask = i + PF_L0;
1614
63.7k
        if (mi->pred_flag & mask) {
1615
67.2k
            for (int j = 0; j < num_cp_mv; j++) {
1616
33.6k
                const Mv *mvd = &mvds[i][j];
1617
33.6k
                mi->mv[i][j].x += mvd->x * (1 << amvr_shift);
1618
33.6k
                mi->mv[i][j].y += mvd->y * (1 << amvr_shift);
1619
33.6k
            }
1620
33.6k
        }
1621
63.7k
    }
1622
31.8k
}
1623
1624
static int mvp_data_ibc(VVCLocalContext *lc)
1625
257k
{
1626
257k
    const VVCFrameContext *fc = lc->fc;
1627
257k
    const CodingUnit *cu      = lc->cu;
1628
257k
    const PredictionUnit *pu  = &lc->cu->pu;
1629
257k
    const VVCSPS *sps         = fc->ps.sps;
1630
257k
    MotionInfo *mi            = &lc->cu->pu.mi;
1631
257k
    int mvp_l0_flag           = 0;
1632
257k
    int amvr_shift            = 4;
1633
257k
    Mv *mv                    = &mi->mv[L0][0];
1634
257k
    int ret;
1635
1636
257k
    mi->pred_flag = PF_IBC;
1637
257k
    mi->num_sb_x  = 1;
1638
257k
    mi->num_sb_y  = 1;
1639
1640
257k
    hls_mvd_coding(lc, mv);
1641
257k
    if (sps->max_num_ibc_merge_cand > 1)
1642
256k
        mvp_l0_flag = ff_vvc_mvp_lx_flag(lc);
1643
257k
    if (sps->r->sps_amvr_enabled_flag && (mv->x || mv->y))
1644
180k
        amvr_shift = ff_vvc_amvr_shift(lc, pu->inter_affine_flag, cu->pred_mode, 1);
1645
1646
257k
    ret = ff_vvc_mvp_ibc(lc, mvp_l0_flag, amvr_shift, mv);
1647
257k
    if (ret)
1648
22.7k
        return ret;
1649
234k
    ff_vvc_store_mv(lc, mi);
1650
1651
234k
    return 0;
1652
257k
}
1653
1654
static int mvp_data(VVCLocalContext *lc)
1655
31.8k
{
1656
31.8k
    const VVCFrameContext *fc       = lc->fc;
1657
31.8k
    const CodingUnit *cu            = lc->cu;
1658
31.8k
    PredictionUnit *pu              = &lc->cu->pu;
1659
31.8k
    const VVCSPS *sps               = fc->ps.sps;
1660
31.8k
    const VVCPH *ph                 = &fc->ps.ph;
1661
31.8k
    const VVCSH *sh                 = &lc->sc->sh;
1662
31.8k
    const H266RawSliceHeader *rsh   = sh->r;
1663
31.8k
    MotionInfo *mi                  = &pu->mi;
1664
31.8k
    const int cb_width              = cu->cb_width;
1665
31.8k
    const int cb_height             = cu->cb_height;
1666
1667
31.8k
    int mvp_lx_flag[2] = {0};
1668
31.8k
    int cu_affine_type_flag = 0;
1669
31.8k
    int num_cp_mv;
1670
31.8k
    int amvr_enabled, has_no_zero_mvd = 0, amvr_shift;
1671
31.8k
    Mv mvds[2][MAX_CONTROL_POINTS];
1672
1673
31.8k
    mi->pred_flag = ff_vvc_pred_flag(lc, IS_B(rsh));
1674
31.8k
    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
31.8k
    mi->motion_model_idc = pu->inter_affine_flag + cu_affine_type_flag;
1681
31.8k
    num_cp_mv = mi->motion_model_idc + 1;
1682
1683
31.8k
    if (sps->r->sps_smvd_enabled_flag && !ph->r->ph_mvd_l1_zero_flag &&
1684
5.90k
        mi->pred_flag == PF_BI && !pu->inter_affine_flag &&
1685
978
        sh->ref_idx_sym[0] > -1 && sh->ref_idx_sym[1] > -1)
1686
179
        pu->sym_mvd_flag = ff_vvc_sym_mvd_flag(lc);
1687
1688
95.5k
    for (int i = L0; i <= L1; i++) {
1689
63.7k
        const PredFlag pred_flag = PF_L0 + !i;
1690
63.7k
        if (mi->pred_flag != pred_flag) {
1691
33.6k
            mi->ref_idx[i] = ref_idx_decode(lc, sh, pu->sym_mvd_flag, i);
1692
33.6k
            has_no_zero_mvd |= mvds_decode(lc, mvds, num_cp_mv, i);
1693
33.6k
            mvp_lx_flag[i] = ff_vvc_mvp_lx_flag(lc);
1694
33.6k
        }
1695
63.7k
    }
1696
1697
31.8k
    amvr_enabled = mi->motion_model_idc == MOTION_TRANSLATION ?
1698
31.8k
        sps->r->sps_amvr_enabled_flag : sps->r->sps_affine_amvr_enabled_flag;
1699
31.8k
    amvr_enabled &= has_no_zero_mvd;
1700
1701
31.8k
    amvr_shift = ff_vvc_amvr_shift(lc, pu->inter_affine_flag, cu->pred_mode, amvr_enabled);
1702
1703
31.8k
    mi->hpel_if_idx = amvr_shift == 3;
1704
31.8k
    mi->bcw_idx = bcw_idx_decode(lc, mi, cb_width, cb_height);
1705
1706
31.8k
    if (mi->motion_model_idc)
1707
0
        ff_vvc_affine_mvp(lc, mvp_lx_flag, amvr_shift, mi);
1708
31.8k
    else
1709
31.8k
        ff_vvc_mvp(lc, mvp_lx_flag, amvr_shift, mi);
1710
1711
31.8k
    mvp_add_difference(mi, num_cp_mv, mvds, amvr_shift);
1712
1713
31.8k
    if (mi->motion_model_idc)
1714
0
        ff_vvc_store_sb_mvs(lc, pu);
1715
31.8k
    else
1716
31.8k
        ff_vvc_store_mv(lc, &pu->mi);
1717
1718
31.8k
    return 0;
1719
31.8k
}
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
73.1k
{
1725
73.1k
    const VVCFrameContext *fc   = lc->fc;
1726
73.1k
    const VVCPPS *pps           = fc->ps.pps;
1727
73.1k
    const VVCPH *ph             = &fc->ps.ph;
1728
73.1k
    const VVCSH *sh             = &lc->sc->sh;
1729
73.1k
    const int poc               = ph->poc;
1730
73.1k
    const MotionInfo *mi        = &pu->mi;
1731
73.1k
    const int8_t *ref_idx       = mi->ref_idx;
1732
73.1k
    const VVCRefPic *rp0        = &lc->sc->rpl[L0].refs[ref_idx[L0]];
1733
73.1k
    const VVCRefPic *rp1        = &lc->sc->rpl[L1].refs[ref_idx[L1]];
1734
73.1k
    const CodingUnit *cu        = lc->cu;
1735
73.1k
    const PredWeightTable *w    = pps->r->pps_wp_info_in_ph_flag ? &fc->ps.ph.pwt : &sh->pwt;
1736
1737
73.1k
    pu->bdof_flag = 0;
1738
1739
73.1k
    if (mi->pred_flag == PF_BI &&
1740
29.1k
        (poc - rp0->poc == rp1->poc - poc) &&
1741
3.93k
        !rp0->is_lt && !rp1->is_lt &&
1742
3.93k
        !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.23k
        !w->weight_flag[L0][CHROMA][ref_idx[L0]] && !w->weight_flag[L1][CHROMA][ref_idx[L1]] &&
1746
2.06k
        cu->cb_width >= 8 && cu->cb_height >= 8 &&
1747
2.06k
        (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
73.1k
}
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
73.1k
{
1764
73.1k
    const CodingUnit *cu    = lc->cu;
1765
73.1k
    PredictionUnit *pu      = &lc->cu->pu;
1766
1767
73.1k
    derive_dmvr_bdof_flag(lc, pu);
1768
73.1k
    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
73.1k
}
1773
1774
static void fill_dmvr_info(const VVCLocalContext *lc)
1775
437k
{
1776
437k
    const VVCFrameContext *fc = lc->fc;
1777
437k
    const CodingUnit *cu      = lc->cu;
1778
1779
437k
    if (cu->pred_mode == MODE_IBC || cu->pred_mode == MODE_PLT) {
1780
351k
        ff_vvc_set_intra_mvf(lc, true, cu->pred_mode == MODE_IBC ? PF_IBC : PF_PLT, false);
1781
351k
    } else {
1782
85.5k
        const VVCPPS *pps = fc->ps.pps;
1783
85.5k
        const int w       = cu->cb_width >> MIN_PU_LOG2;
1784
1785
238k
        for (int y = cu->y0 >> MIN_PU_LOG2; y < (cu->y0 + cu->cb_height) >> MIN_PU_LOG2; y++) {
1786
153k
            const int idx = pps->min_pu_width * y + (cu->x0 >> MIN_PU_LOG2);
1787
153k
            const MvField *mvf = fc->tab.mvf + idx;
1788
153k
            MvField *dmvr_mvf  = fc->ref->tab_dmvr_mvf + idx;
1789
1790
153k
            memcpy(dmvr_mvf, mvf, sizeof(MvField) * w);
1791
153k
        }
1792
85.5k
    }
1793
437k
}
1794
1795
static int inter_data(VVCLocalContext *lc)
1796
459k
{
1797
459k
    const CodingUnit *cu    = lc->cu;
1798
459k
    PredictionUnit *pu      = &lc->cu->pu;
1799
459k
    const MotionInfo *mi    = &pu->mi;
1800
459k
    int ret                 = 0;
1801
1802
459k
    pu->general_merge_flag = 1;
1803
459k
    if (!cu->skip_flag)
1804
405k
        pu->general_merge_flag = ff_vvc_general_merge_flag(lc);
1805
1806
459k
    if (pu->general_merge_flag) {
1807
170k
        ret = hls_merge_data(lc);
1808
289k
    } else if (cu->pred_mode == MODE_IBC) {
1809
257k
        ret = mvp_data_ibc(lc);
1810
257k
    } else {
1811
31.8k
        ret = mvp_data(lc);
1812
31.8k
    }
1813
1814
459k
    if (ret)
1815
22.8k
        return ret;
1816
1817
437k
    if (cu->pred_mode == MODE_IBC) {
1818
351k
        ff_vvc_update_hmvp(lc, mi);
1819
351k
    } else if (!pu->merge_gpm_flag && !pu->inter_affine_flag && !pu->merge_subblock_flag) {
1820
73.1k
        refine_regular_subblock(lc);
1821
73.1k
        ff_vvc_update_hmvp(lc, mi);
1822
73.1k
    }
1823
1824
437k
    if (!pu->dmvr_flag)
1825
437k
        fill_dmvr_info(lc);
1826
437k
    return ret;
1827
459k
}
1828
1829
static TransformUnit* palette_add_tu(VVCLocalContext *lc, const int start, const int end, const VVCTreeType tree_type)
1830
88.4k
{
1831
88.4k
    CodingUnit   *cu  = lc->cu;
1832
88.4k
    const VVCSPS *sps = lc->fc->ps.sps;
1833
88.4k
    TransformUnit *tu = add_tu(lc->fc, cu, cu->x0, cu->y0, cu->cb_width, cu->cb_height);
1834
1835
88.4k
    if (!tu)
1836
0
        return NULL;
1837
1838
267k
    for (int c = start; c < end; c++) {
1839
179k
        const int w = tu->width >> sps->hshift[c];
1840
179k
        const int h = tu->height >> sps->vshift[c];
1841
179k
        TransformBlock *tb = add_tb(tu, lc, tu->x0, tu->y0, w, h, c);
1842
179k
        if (c != CR)
1843
103k
            set_tb_size(lc->fc, tb);
1844
179k
    }
1845
1846
353k
    for (int i = 0; i < FF_ARRAY_ELEMS(cu->plt); i++)
1847
265k
        cu->plt[i].size = 0;
1848
1849
88.4k
    return tu;
1850
88.4k
}
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
88.4k
{
1855
88.4k
    CodingUnit  *cu  = lc->cu;
1856
88.4k
    int nb_predicted = 0;
1857
1858
88.4k
    if (local_dual_tree) {
1859
984
        start = LUMA;
1860
984
        end = VVC_MAX_SAMPLE_ARRAYS;
1861
984
    }
1862
1863
89.4k
    for (int i = 0; i < predictor_size && nb_predicted < max_entries; i++) {
1864
1.58k
        const int run = ff_vvc_palette_predictor_run(lc, predictor_size - i);
1865
1.58k
        if (run < 0)
1866
161
            return run;
1867
1868
1.41k
        if (run == 1)
1869
438
            break;
1870
1871
981
        if (run > 1)
1872
143
            i += run - 1;
1873
1874
981
        predictor_reused[i] = true;
1875
3.19k
        for (int c = start; c < end; c++)
1876
2.21k
            cu->plt[c].entries[nb_predicted] = lc->ep->pp[c].entries[i];
1877
981
        nb_predicted++;
1878
981
    }
1879
1880
269k
    for (int c = start; c < end; c++)
1881
180k
        cu->plt[c].size = nb_predicted;
1882
1883
88.3k
    return 0;
1884
88.4k
}
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
88.3k
{
1889
88.3k
    const VVCSPS *sps         = lc->fc->ps.sps;
1890
88.3k
    CodingUnit  *cu           = lc->cu;
1891
88.3k
    const int nb_predicted    = cu->plt[start].size;
1892
88.3k
    const int nb_signaled     = nb_predicted < max_entries ? ff_vvc_num_signalled_palette_entries(lc, max_entries - nb_predicted) : 0;
1893
88.3k
    const int size            = nb_predicted + nb_signaled;
1894
88.3k
    const bool dual_tree_luma = local_dual_tree && cu->tree_type == DUAL_TREE_LUMA;
1895
1896
88.3k
    if (nb_signaled < 0)
1897
473
        return AVERROR_INVALIDDATA;
1898
1899
265k
    for (int c = start; c < end; c++) {
1900
177k
        Palette *plt = cu->plt + c;
1901
878k
        for (int i = nb_predicted; i < size; i++) {
1902
700k
            plt->entries[i] = ff_vvc_new_palette_entries(lc, sps->bit_depth);
1903
700k
            if (dual_tree_luma) {
1904
397
                plt[CB].entries[i] = 1 << (sps->bit_depth - 1);
1905
397
                plt[CR].entries[i] = 1 << (sps->bit_depth - 1);
1906
397
            }
1907
700k
        }
1908
177k
        plt->size = size;
1909
177k
    }
1910
1911
87.8k
    return 0;
1912
88.3k
}
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
87.8k
{
1917
87.8k
    CodingUnit  *cu         = lc->cu;
1918
87.8k
    const int max_predictor = VVC_MAX_NUM_PALETTE_PREDICTOR_SIZE >> (cu->tree_type != SINGLE_TREE && !local_dual_tree);
1919
1920
87.8k
    if (local_dual_tree) {
1921
728
        start = LUMA;
1922
728
        end = VVC_MAX_SAMPLE_ARRAYS;
1923
728
    }
1924
1925
267k
    for (int c = start; c < end; c++) {
1926
179k
        Palette *pp  = lc->ep->pp + c;
1927
179k
        Palette *plt = cu->plt + c;
1928
179k
        int i = cu->plt[start].size;;
1929
1930
        // copy unused predictors to the end of plt
1931
183k
        for (int j = 0; j < predictor_size && i < max_predictor; j++) {
1932
4.05k
            if (!predictor_reused[j]) {
1933
2.04k
                plt->entries[i] = pp->entries[j];
1934
2.04k
                i++;
1935
2.04k
            }
1936
4.05k
        }
1937
1938
179k
        memcpy(pp->entries, plt->entries, i * sizeof(pp->entries[0]));
1939
179k
        pp->size = i;
1940
179k
    }
1941
87.8k
}
1942
1943
static int palette_qp(VVCLocalContext *lc, VVCTreeType tree_type, const bool escape_present)
1944
87.8k
{
1945
87.8k
    const VVCFrameContext *fc     = lc->fc;
1946
87.8k
    const VVCPPS *pps             = fc->ps.pps;
1947
87.8k
    const H266RawSliceHeader *rsh = lc->sc->sh.r;
1948
87.8k
    const CodingUnit *cu          = lc->cu;
1949
87.8k
    int ret;
1950
1951
87.8k
    if (tree_type != DUAL_TREE_CHROMA) {
1952
26.5k
        const bool has_qp_delta = escape_present &&
1953
13.0k
            pps->r->pps_cu_qp_delta_enabled_flag && !lc->parse.is_cu_qp_delta_coded;
1954
26.5k
        ret = set_qp_y(lc, cu->x0, cu->y0, has_qp_delta);
1955
26.5k
        if (ret < 0)
1956
4
            return ret;
1957
26.5k
    }
1958
1959
87.8k
    if (tree_type != DUAL_TREE_LUMA) {
1960
76.4k
        if (rsh->sh_cu_chroma_qp_offset_enabled_flag && !lc->parse.is_cu_chroma_qp_offset_coded)
1961
282
            chroma_qp_offset_decode(lc, 0, 1);
1962
76.4k
        set_qp_c(lc);
1963
76.4k
    }
1964
1965
87.8k
    return 0;
1966
87.8k
}
1967
1968
#define PALETTE_SET_PIXEL(xc, yc, pix)                              \
1969
9.70M
    do {                                                            \
1970
9.70M
        const int off = ((xc) >> hs) + ((yc) >> vs) * tb->tb_width; \
1971
9.70M
        if (sps->bit_depth == 8)                                    \
1972
9.70M
            u8[off] = pix;                                          \
1973
9.70M
        else                                                        \
1974
9.70M
            u16[off] = pix;                                         \
1975
9.70M
    } while (0)
1976
1977
20.7M
#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
25.4M
#define TRAV_COL(p, wlog, mask) ((p & mask) ^ (-((p >> wlog) & 1) & mask))
1983
25.4M
#define TRAV_ROW(p, hlog) (p >> hlog)
1984
50.9M
#define TRAV(trans, p, wlog, hlog, mask)  (trans ? TRAV_ROW((p), hlog) : TRAV_COL((p), wlog, mask))
1985
25.4M
#define TRAV_X(pos) TRAV(transpose, pos, wlog2, hlog2, wmask)
1986
25.4M
#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
328k
{
1992
328k
    const CodingUnit *cu = lc->cu;
1993
328k
    TransformUnit *tu    = cu->tus.head;
1994
328k
    const VVCSPS *sps    = lc->fc->ps.sps;
1995
328k
    const int width      = tu->tbs[0].tb_width;
1996
328k
    const int height     = tu->tbs[0].tb_height;
1997
328k
    const int min_pos    = subset_id << 4;
1998
328k
    const int max_pos    = FFMIN(min_pos + 16, width * height);
1999
328k
    const int wmask      = width  - 1;
2000
328k
    const int hmask      = height - 1;
2001
328k
    const int wlog2      = av_log2(width);
2002
328k
    const int hlog2      = av_log2(height);
2003
328k
    const int start_idx  = tu->tbs[0].c_idx;
2004
328k
    const uint8_t esc    = cu->plt[tu->tbs[0].c_idx].size;
2005
328k
    uint8_t run_copy[16] = { 0 };
2006
2007
5.58M
    for (int i = min_pos; i < max_pos; i++) {
2008
5.25M
        const int xc = TRAV_X(i);
2009
5.25M
        const int yc = TRAV_Y(i);
2010
2011
5.25M
        if (i > 0 && max_index > 0)
2012
4.64M
            run_copy[i - min_pos] = ff_vvc_run_copy_flag(lc, run_type[i - 1], *prev_run_pos, i);
2013
2014
5.25M
        run_type[i] = 0;
2015
5.25M
        if (max_index > 0 && !run_copy[i - min_pos]) {
2016
923k
            if (((!transpose && yc > 0) || (transpose && xc > 0))
2017
561k
                && i > 0 && !run_type[i - 1]) {
2018
416k
                run_type[i] = ff_vvc_copy_above_palette_indices_flag(lc);
2019
416k
            }
2020
923k
            *prev_run_pos = i;
2021
4.33M
        } else if (i > 0) {
2022
4.32M
            run_type[i] = run_type[i - 1];
2023
4.32M
        }
2024
5.25M
    }
2025
2026
5.58M
    for (int i = min_pos; i < max_pos; i++) {
2027
5.25M
        const int xc = TRAV_X(i);
2028
5.25M
        const int yc = TRAV_Y(i);
2029
5.25M
        const int prev_xc = i > 0 ? TRAV_X(i - 1) : 0;
2030
5.25M
        const int prev_yc = i > 0 ? TRAV_Y(i - 1) : 0;
2031
2032
5.25M
        int idx = 0;
2033
5.25M
        if (max_index > 0 && !run_copy[i - min_pos] && !run_type[i]) {
2034
769k
            if (max_index - *adjust > 0)
2035
681k
                idx = ff_vvc_palette_idx_idc(lc, max_index, *adjust);
2036
769k
            if (i > 0) {
2037
694k
                const int ref_idx = !run_type[i - 1] ?
2038
549k
                    PALETTE_INDEX(prev_xc, prev_yc) : PALETTE_INDEX(xc - transpose, yc - !transpose);
2039
694k
                idx += (idx >= ref_idx);
2040
694k
            }
2041
769k
            *adjust = true;
2042
4.48M
        } else {
2043
4.48M
            idx = PALETTE_INDEX(prev_xc, prev_yc);
2044
4.48M
        }
2045
2046
5.25M
        if (!run_type[i])
2047
4.64M
            PALETTE_INDEX(xc, yc) = idx;
2048
617k
        else
2049
617k
            PALETTE_INDEX(xc, yc) = PALETTE_INDEX(xc - transpose, yc - !transpose);
2050
5.25M
    }
2051
2052
933k
    for (int c = 0; c < tu->nb_tbs; c++) {
2053
614k
        TransformBlock *tb = &tu->tbs[c];
2054
614k
        const int c_idx    = tb->c_idx;
2055
614k
        const Palette *plt = &cu->plt[c_idx];
2056
614k
        const int scale    = ff_vvc_palette_derive_scale(lc, tu, tb);
2057
614k
        const int hs       = sps->hshift[c_idx] - sps->hshift[start_idx];
2058
614k
        const int vs       = sps->vshift[c_idx] - sps->vshift[start_idx];
2059
614k
        uint8_t *u8        = (uint8_t *)tb->coeffs;
2060
614k
        uint16_t *u16      = (uint16_t *)tb->coeffs;
2061
2062
10.3M
        for (int i = min_pos; i < max_pos; i++) {
2063
9.76M
            const int xc = TRAV_X(i);
2064
9.76M
            const int yc = TRAV_Y(i);
2065
9.76M
            if (!(xc & hs) && !(yc & vs)) {
2066
9.71M
                const int v = PALETTE_INDEX(xc, yc);
2067
9.71M
                if (v == esc) {
2068
951k
                    const int coeff = ff_vvc_palette_escape_val(lc, (1 << sps->bit_depth) - 1);
2069
951k
                    if (coeff < 0)
2070
9.54k
                        return AVERROR_INVALIDDATA;
2071
942k
                    const int pixel = av_clip_intp2(RSHIFT(coeff * scale, 6), sps->bit_depth);
2072
942k
                    PALETTE_SET_PIXEL(xc, yc, pixel);
2073
8.76M
                } else {
2074
8.76M
                    PALETTE_SET_PIXEL(xc, yc, plt->entries[v]);
2075
8.76M
                }
2076
9.71M
            }
2077
9.76M
        }
2078
614k
    }
2079
2080
319k
    return 0;
2081
328k
}
2082
2083
static int hls_palette_coding(VVCLocalContext *lc, const VVCTreeType tree_type)
2084
88.4k
{
2085
88.4k
    const VVCFrameContext *fc     = lc->fc;
2086
88.4k
    const VVCSPS *sps             = fc->ps.sps;
2087
88.4k
    const H266RawSliceHeader *rsh = lc->sc->sh.r;
2088
88.4k
    CodingUnit *cu                = lc->cu;
2089
88.4k
    Palette *pp                   = lc->ep->pp;
2090
88.4k
    const int max_entries         = tree_type == SINGLE_TREE ? 31 : 15;
2091
88.4k
    const bool local_dual_tree    = tree_type != SINGLE_TREE &&
2092
73.0k
                                        (!IS_I(rsh) || (IS_I(rsh) && !sps->r->sps_qtbtt_dual_tree_intra_flag));
2093
88.4k
    bool escape_present           = false;
2094
88.4k
    bool transpose                = false;
2095
88.4k
    bool adjust                   = false;
2096
88.4k
    int max_index                 = 0;
2097
88.4k
    int prev_run_pos              = 0;
2098
2099
88.4k
    int predictor_size, start, end, ret;
2100
88.4k
    bool reused[VVC_MAX_NUM_PALETTE_PREDICTOR_SIZE];
2101
88.4k
    uint8_t run_type[MAX_PALETTE_CU_SIZE * MAX_PALETTE_CU_SIZE];
2102
88.4k
    uint8_t index[MAX_PALETTE_CU_SIZE * MAX_PALETTE_CU_SIZE];
2103
2104
88.4k
    TransformUnit *tu;
2105
2106
88.4k
    ff_vvc_channel_range(&start, &end, tree_type, sps->r->sps_chroma_format_idc);
2107
2108
88.4k
    tu = palette_add_tu(lc, start, end, tree_type);
2109
88.4k
    if (!tu)
2110
0
        return AVERROR(ENOMEM);
2111
2112
88.4k
    predictor_size = pp[start].size;
2113
88.4k
    memset(reused, 0, sizeof(reused[0]) * predictor_size);
2114
2115
88.4k
    ret = palette_predicted(lc, local_dual_tree, start, end, reused, predictor_size, max_entries);
2116
88.4k
    if (ret < 0)
2117
161
        return ret;
2118
2119
88.3k
    ret = palette_signaled(lc, local_dual_tree, start, end, max_entries);
2120
88.3k
    if (ret < 0)
2121
473
        return ret;
2122
2123
87.8k
    palette_update_predictor(lc, local_dual_tree, start, end, reused, predictor_size);
2124
2125
87.8k
    if (cu->plt[start].size > 0)
2126
76.9k
        escape_present = ff_vvc_palette_escape_val_present_flag(lc);
2127
2128
87.8k
    max_index = cu->plt[start].size - 1 + escape_present;
2129
87.8k
    if (max_index > 0) {
2130
75.8k
        adjust = false;
2131
75.8k
        transpose = ff_vvc_palette_transpose_flag(lc);
2132
75.8k
    }
2133
2134
87.8k
    ret = palette_qp(lc, tree_type, escape_present);
2135
87.8k
    if (ret < 0)
2136
4
        return ret;
2137
2138
87.8k
    index[0] = 0;
2139
406k
    for (int i = 0; i <= (tu->tbs[0].tb_width * tu->tbs[0].tb_height - 1) >> 4; i++) {
2140
328k
        ret = palette_subblock_data(lc, max_index, i, transpose,
2141
328k
            run_type, index, &prev_run_pos, &adjust);
2142
328k
        if (ret < 0)
2143
9.54k
            return ret;
2144
328k
    }
2145
2146
78.2k
    return 0;
2147
87.8k
}
2148
2149
static int intra_data(VVCLocalContext *lc)
2150
8.06M
{
2151
8.06M
    const VVCSPS *sps              = lc->fc->ps.sps;
2152
8.06M
    const CodingUnit *cu           = lc->cu;
2153
8.06M
    const VVCTreeType tree_type    = cu->tree_type;
2154
8.06M
    const bool  pred_mode_plt_flag = cu->pred_mode == MODE_PLT;
2155
8.06M
    int ret                        = 0;
2156
2157
8.06M
    if (tree_type == SINGLE_TREE || tree_type == DUAL_TREE_LUMA) {
2158
5.44M
        if (pred_mode_plt_flag) {
2159
27.1k
            if ((ret = hls_palette_coding(lc, tree_type)) < 0)
2160
9.64k
                return ret;
2161
17.4k
            ff_vvc_set_intra_mvf(lc, false, PF_PLT, false);
2162
5.41M
        } else {
2163
5.41M
            intra_luma_pred_modes(lc);
2164
5.41M
            ff_vvc_set_intra_mvf(lc, false, PF_INTRA, cu->ciip_flag);
2165
5.41M
        }
2166
5.44M
    }
2167
8.05M
    if ((tree_type == SINGLE_TREE || tree_type == DUAL_TREE_CHROMA) && sps->r->sps_chroma_format_idc) {
2168
3.38M
        if (pred_mode_plt_flag && tree_type == DUAL_TREE_CHROMA) {
2169
61.3k
            if ((ret = hls_palette_coding(lc, tree_type)) < 0)
2170
543
                return ret;
2171
3.31M
        } else if (!pred_mode_plt_flag) {
2172
3.31M
            intra_chroma_pred_modes(lc);
2173
3.31M
        }
2174
3.38M
    }
2175
2176
8.05M
    return ret;
2177
8.05M
}
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
8.52M
{
2182
8.52M
    const VVCFrameContext *fc     = lc->fc;
2183
8.52M
    const VVCSPS *sps             = fc->ps.sps;
2184
8.52M
    const H266RawSliceHeader *rsh = lc->sc->sh.r;
2185
8.52M
    const int is_128              = cb_width > 64 || cb_height > 64;
2186
8.52M
    int ret                       = 0;
2187
2188
8.52M
    CodingUnit *cu = add_cu(lc, x0, y0, cb_width, cb_height, cqt_depth, tree_type);
2189
2190
8.52M
    if (!cu)
2191
0
        return AVERROR(ENOMEM);
2192
2193
8.52M
    ff_vvc_set_neighbour_available(lc, cu->x0, cu->y0, cu->cb_width, cu->cb_height);
2194
2195
8.52M
    if (IS_I(rsh) && is_128)
2196
0
        mode_type = MODE_TYPE_INTRA;
2197
8.52M
    cu->pred_mode = pred_mode_decode(lc, tree_type, mode_type);
2198
2199
8.52M
    if (cu->pred_mode == MODE_INTRA && sps->r->sps_act_enabled_flag && tree_type == SINGLE_TREE)
2200
294k
        cu->act_enabled_flag = ff_vvc_cu_act_enabled_flag(lc);
2201
2202
8.52M
    if (cu->pred_mode == MODE_INTRA || cu->pred_mode == MODE_PLT)
2203
8.06M
        ret = intra_data(lc);
2204
459k
    else if (tree_type != DUAL_TREE_CHROMA) /* MODE_INTER or MODE_IBC */
2205
459k
        ret = inter_data(lc);
2206
2207
8.52M
    if (ret < 0)
2208
33.0k
        return ret;
2209
2210
8.48M
    if (cu->pred_mode != MODE_INTRA && cu->pred_mode != MODE_PLT && !lc->cu->pu.general_merge_flag)
2211
266k
        cu->coded_flag = ff_vvc_cu_coded_flag(lc);
2212
8.22M
    else
2213
8.22M
        cu->coded_flag = !(cu->skip_flag || cu->pred_mode == MODE_PLT);
2214
2215
8.48M
    if (cu->coded_flag) {
2216
8.25M
        sbt_info(lc, sps);
2217
8.25M
        if (sps->r->sps_act_enabled_flag && cu->pred_mode != MODE_INTRA && tree_type == SINGLE_TREE)
2218
5.32k
            cu->act_enabled_flag = ff_vvc_cu_act_enabled_flag(lc);
2219
8.25M
        lc->parse.lfnst_dc_only = 1;
2220
8.25M
        lc->parse.lfnst_zero_out_sig_coeff_flag = 1;
2221
8.25M
        lc->parse.mts_dc_only = 1;
2222
8.25M
        lc->parse.mts_zero_out_sig_coeff_flag = 1;
2223
8.25M
        ret = hls_transform_tree(lc, x0, y0, cb_width, cb_height, cu->ch_type);
2224
8.25M
        if (ret < 0)
2225
2.31k
            return ret;
2226
8.25M
        cu->lfnst_idx = lfnst_idx_decode(lc);
2227
8.25M
        cu->mts_idx = mts_idx_decode(lc);
2228
8.25M
        set_qp_c(lc);
2229
8.25M
    } else if (cu->pred_mode != MODE_PLT) {
2230
152k
        ret = skipped_transform_tree_unit(lc);
2231
152k
        if (ret < 0)
2232
0
            return ret;
2233
152k
    }
2234
8.48M
    set_cu_tabs(lc, cu);
2235
2236
8.48M
    return 0;
2237
8.48M
}
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.0M
{
2242
10.0M
    const H266RawSliceHeader *rsh   = lc->sc->sh.r;
2243
10.0M
    const VVCSPS *sps               = lc->fc->ps.sps;
2244
10.0M
    const int area                  = cb_width * cb_height;
2245
2246
10.0M
    if ((IS_I(rsh) && sps->r->sps_qtbtt_dual_tree_intra_flag) ||
2247
3.75M
        mode_type_curr != MODE_TYPE_ALL || !sps->r->sps_chroma_format_idc ||
2248
3.60M
        sps->r->sps_chroma_format_idc == CHROMA_FORMAT_444)
2249
8.12M
        return 0;
2250
1.93M
    if ((area == 64 && (split == SPLIT_QT || split == SPLIT_TT_HOR || split == SPLIT_TT_VER)) ||
2251
1.70M
        (area == 32 &&  (split == SPLIT_BT_HOR || split == SPLIT_BT_VER)))
2252
237k
        return 1;
2253
1.70M
    if ((area == 64 && (split == SPLIT_BT_HOR || split == SPLIT_BT_VER) && sps->r->sps_chroma_format_idc == CHROMA_FORMAT_420) ||
2254
1.60M
        (area == 128 && (split == SPLIT_TT_HOR || split == SPLIT_TT_VER) && sps->r->sps_chroma_format_idc == CHROMA_FORMAT_420) ||
2255
1.60M
        (cb_width == 8 && split == SPLIT_BT_VER) || (cb_width == 16 && split == SPLIT_TT_VER))
2256
99.5k
        return 1 + !IS_I(rsh);
2257
2258
1.60M
    return 0;
2259
1.70M
}
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.0M
{
2265
10.0M
    VVCModeType mode_type;
2266
10.0M
    const int mode_type_condition = derive_mode_type_condition(lc, split, cb_width, cb_height, mode_type_curr);
2267
2268
10.0M
    if (mode_type_condition == 1)
2269
322k
        mode_type = MODE_TYPE_INTRA;
2270
9.73M
    else if (mode_type_condition == 2) {
2271
14.1k
        mode_type = ff_vvc_non_inter_flag(lc, x0, y0, ch_type) ? MODE_TYPE_INTRA : MODE_TYPE_INTER;
2272
9.72M
    } else {
2273
9.72M
        mode_type = mode_type_curr;
2274
9.72M
    }
2275
2276
10.0M
    return mode_type;
2277
10.0M
}
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
978k
{
2289
1.47M
#define CODING_TREE(x, idx) do { \
2290
1.47M
    ret = hls_coding_tree(lc, x, y0, cb_width / 2, cb_height, \
2291
1.47M
        qg_on_y, qg_on_c, cb_sub_div + 1, cqt_depth, mtt_depth + 1, \
2292
1.47M
        depth_offset, idx, SPLIT_BT_VER, tree_type, mode_type); \
2293
1.47M
    if (ret < 0) \
2294
1.47M
        return ret; \
2295
1.47M
} while (0);
2296
2297
978k
    const VVCPPS *pps = lc->fc->ps.pps;
2298
978k
    const int x1 = x0 + cb_width / 2;
2299
978k
    int ret = 0;
2300
2301
978k
    depth_offset += (x0 + cb_width > pps->width) ? 1 : 0;
2302
978k
    CODING_TREE(x0, 0);
2303
973k
    if (x1 < pps->width)
2304
966k
        CODING_TREE(x1, 1);
2305
2306
966k
    return 0;
2307
2308
973k
#undef CODING_TREE
2309
973k
}
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.65M
{
2316
2.76M
#define CODING_TREE(y, idx) do { \
2317
2.76M
        ret = hls_coding_tree(lc, x0, y, cb_width , cb_height / 2, \
2318
2.76M
            qg_on_y, qg_on_c, cb_sub_div + 1, cqt_depth, mtt_depth + 1, \
2319
2.76M
            depth_offset, idx, SPLIT_BT_HOR, tree_type, mode_type); \
2320
2.76M
        if (ret < 0) \
2321
2.76M
            return ret; \
2322
2.76M
    } while (0);
2323
2324
1.65M
    const VVCPPS *pps = lc->fc->ps.pps;
2325
1.65M
    const int y1 = y0 + (cb_height / 2);
2326
1.65M
    int ret = 0;
2327
2328
1.65M
    depth_offset += (y0 + cb_height > pps->height) ? 1 : 0;
2329
1.65M
    CODING_TREE(y0, 0);
2330
1.65M
    if (y1 < pps->height)
2331
1.65M
        CODING_TREE(y1, 1);
2332
2333
1.65M
    return 0;
2334
2335
1.65M
#undef CODING_TREE
2336
1.65M
}
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
117k
{
2343
352k
#define CODING_TREE(x, w, sub_div, idx) do { \
2344
352k
        ret = hls_coding_tree(lc, x, y0, w, cb_height, \
2345
352k
            qg_on_y, qg_on_c, sub_div, cqt_depth, mtt_depth + 1, \
2346
352k
            depth_offset, idx, SPLIT_TT_VER, tree_type, mode_type); \
2347
352k
        if (ret < 0) \
2348
352k
            return ret; \
2349
352k
    } while (0);
2350
2351
117k
    const VVCSH *sh = &lc->sc->sh;
2352
117k
    const int x1    = x0 + cb_width / 4;
2353
117k
    const int x2    = x0 + cb_width * 3 / 4;
2354
117k
    int ret;
2355
2356
117k
    qg_on_y = qg_on_y && (cb_sub_div + 2 <= sh->cu_qp_delta_subdiv);
2357
117k
    qg_on_c = qg_on_c && (cb_sub_div + 2 <= sh->cu_chroma_qp_offset_subdiv);
2358
2359
117k
    CODING_TREE(x0, cb_width / 4, cb_sub_div + 2, 0);
2360
117k
    CODING_TREE(x1, cb_width / 2, cb_sub_div + 1, 1);
2361
117k
    CODING_TREE(x2, cb_width / 4, cb_sub_div + 2, 2);
2362
2363
117k
    return 0;
2364
2365
117k
#undef CODING_TREE
2366
117k
}
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
138k
{
2373
415k
#define CODING_TREE(y, h, sub_div, idx) do { \
2374
415k
        ret = hls_coding_tree(lc, x0, y, cb_width, h, \
2375
415k
            qg_on_y, qg_on_c, sub_div, cqt_depth, mtt_depth + 1, \
2376
415k
            depth_offset, idx, SPLIT_TT_HOR, tree_type, mode_type); \
2377
415k
        if (ret < 0) \
2378
415k
            return ret; \
2379
415k
    } while (0);
2380
2381
138k
    const VVCSH *sh = &lc->sc->sh;
2382
138k
    const int y1    = y0 + (cb_height / 4);
2383
138k
    const int y2    = y0 + (3 * cb_height / 4);
2384
138k
    int ret;
2385
2386
138k
    qg_on_y = qg_on_y && (cb_sub_div + 2 <= sh->cu_qp_delta_subdiv);
2387
138k
    qg_on_c = qg_on_c && (cb_sub_div + 2 <= sh->cu_chroma_qp_offset_subdiv);
2388
2389
138k
    CODING_TREE(y0, cb_height / 4, cb_sub_div + 2, 0);
2390
138k
    CODING_TREE(y1, cb_height / 2, cb_sub_div + 1, 1);
2391
138k
    CODING_TREE(y2, cb_height / 4, cb_sub_div + 2, 2);
2392
2393
138k
    return 0;
2394
2395
138k
#undef CODING_TREE
2396
138k
}
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
7.16M
{
2403
10.5M
#define CODING_TREE(x, y, idx) do { \
2404
10.5M
        ret = hls_coding_tree(lc, x, y, cb_width / 2, cb_height / 2, \
2405
10.5M
            qg_on_y, qg_on_c, cb_sub_div + 2, cqt_depth + 1, 0, 0, \
2406
10.5M
            idx, SPLIT_QT, tree_type, mode_type); \
2407
10.5M
        if (ret < 0) \
2408
10.5M
            return ret; \
2409
10.5M
    } while (0);
2410
2411
7.16M
    const VVCPPS *pps = lc->fc->ps.pps;
2412
7.16M
    const int x1 = x0 + cb_width / 2;
2413
7.16M
    const int y1 = y0 + cb_height / 2;
2414
7.16M
    int ret = 0;
2415
2416
7.16M
    CODING_TREE(x0, y0, 0);
2417
7.06M
    if (x1 < pps->width)
2418
7.05M
        CODING_TREE(x1, y0, 1);
2419
7.05M
    if (y1 < pps->height)
2420
7.05M
        CODING_TREE(x0, y1, 2);
2421
7.05M
    if (x1 < pps->width &&
2422
1.11M
        y1 < pps->height)
2423
7.05M
        CODING_TREE(x1, y1, 3);
2424
2425
7.05M
    return 0;
2426
2427
7.05M
#undef CODING_TREE
2428
7.05M
}
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
18.5M
{
2448
18.5M
    VVCFrameContext *fc             = lc->fc;
2449
18.5M
    const VVCPPS *pps               = fc->ps.pps;
2450
18.5M
    const VVCSH *sh                 = &lc->sc->sh;
2451
18.5M
    const H266RawSliceHeader *rsh   = sh->r;
2452
18.5M
    const int ch_type               = tree_type_curr == DUAL_TREE_CHROMA;
2453
18.5M
    int ret;
2454
18.5M
    VVCAllowedSplit allowed;
2455
2456
18.5M
    if (pps->r->pps_cu_qp_delta_enabled_flag && qg_on_y && cb_sub_div <= sh->cu_qp_delta_subdiv) {
2457
853k
        lc->parse.is_cu_qp_delta_coded = 0;
2458
853k
        lc->parse.cu_qg_top_left_x = x0;
2459
853k
        lc->parse.cu_qg_top_left_y = y0;
2460
853k
    }
2461
18.5M
    if (rsh->sh_cu_chroma_qp_offset_enabled_flag && qg_on_c &&
2462
437k
        cb_sub_div <= sh->cu_chroma_qp_offset_subdiv) {
2463
84.4k
        lc->parse.is_cu_chroma_qp_offset_coded = 0;
2464
84.4k
        memset(lc->parse.chroma_qp_offset, 0, sizeof(lc->parse.chroma_qp_offset));
2465
84.4k
    }
2466
2467
18.5M
    can_split(lc, x0, y0, cb_width, cb_height, mtt_depth, depth_offset, part_idx,
2468
18.5M
        last_split_mode, tree_type_curr, mode_type_curr, &allowed);
2469
18.5M
    if (ff_vvc_split_cu_flag(lc, x0, y0, cb_width, cb_height, ch_type, &allowed)) {
2470
10.0M
        VVCSplitMode split      = ff_vvc_split_mode(lc, x0, y0, cb_width, cb_height, cqt_depth, mtt_depth, ch_type, &allowed);
2471
10.0M
        VVCModeType mode_type   = mode_type_decode(lc, x0, y0, cb_width, cb_height, split, ch_type, mode_type_curr);
2472
2473
10.0M
        VVCTreeType tree_type   = (mode_type == MODE_TYPE_INTRA) ? DUAL_TREE_LUMA : tree_type_curr;
2474
2475
10.0M
        if (split != SPLIT_QT) {
2476
2.89M
            if (!(x0 & 31) && !(y0 & 31) && mtt_depth <= 1)
2477
1.83M
                TAB_MSM(fc, mtt_depth, x0, y0) = split;
2478
2.89M
        }
2479
10.0M
        ret = coding_tree[split - 1](lc, x0, y0, cb_width, cb_height, qg_on_y, qg_on_c,
2480
10.0M
            cb_sub_div, cqt_depth, mtt_depth, depth_offset, tree_type, mode_type);
2481
10.0M
        if (ret < 0)
2482
134k
            return ret;
2483
9.92M
        if (mode_type_curr == MODE_TYPE_ALL && mode_type == MODE_TYPE_INTRA) {
2484
315k
            ret = hls_coding_tree(lc, x0, y0, cb_width, cb_height, 0, qg_on_c, cb_sub_div,
2485
315k
                cqt_depth, mtt_depth, 0, 0, split, DUAL_TREE_CHROMA, mode_type);
2486
315k
            if (ret < 0)
2487
0
                return ret;
2488
315k
        }
2489
9.92M
    } else {
2490
8.52M
        ret = hls_coding_unit(lc, x0, y0, cb_width, cb_height, cqt_depth, tree_type_curr, mode_type_curr);
2491
8.52M
        if (ret < 0)
2492
35.3k
            return ret;
2493
8.52M
    }
2494
2495
18.4M
    return 0;
2496
18.5M
}
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.02M
{
2501
1.02M
    const VVCSH *sh                 = &lc->sc->sh;
2502
1.02M
    const H266RawSliceHeader *rsh   = sh->r;
2503
1.02M
    const VVCPPS *pps               = lc->fc->ps.pps;
2504
1.02M
    const int cb_subdiv             = 2 * cqt_depth;
2505
1.02M
    int ret;
2506
2507
1.02M
    if (cb_size > 64) {
2508
299k
        #define DUAL_TREE(x, y) do {                                                \
2509
299k
            ret = dual_tree_implicit_qt_split(lc, x, y, cb_size / 2, cqt_depth + 1); \
2510
299k
            if (ret < 0)                                                            \
2511
299k
                return ret;                                                         \
2512
299k
        } while (0)
2513
2514
90.2k
        const int x1 = x0 + (cb_size / 2);
2515
90.2k
        const int y1 = y0 + (cb_size / 2);
2516
90.2k
        if (pps->r->pps_cu_qp_delta_enabled_flag && cb_subdiv <= sh->cu_qp_delta_subdiv) {
2517
882
            lc->parse.is_cu_qp_delta_coded = 0;
2518
882
            lc->parse.cu_qg_top_left_x = x0;
2519
882
            lc->parse.cu_qg_top_left_y = y0;
2520
882
        }
2521
90.2k
        if (rsh->sh_cu_chroma_qp_offset_enabled_flag && cb_subdiv <= sh->cu_chroma_qp_offset_subdiv) {
2522
219
            lc->parse.is_cu_chroma_qp_offset_coded = 0;
2523
219
            memset(lc->parse.chroma_qp_offset, 0, sizeof(lc->parse.chroma_qp_offset));
2524
219
        }
2525
90.2k
        DUAL_TREE(x0, y0);
2526
89.8k
        if (x1 < pps->width)
2527
75.4k
            DUAL_TREE(x1, y0);
2528
89.7k
        if (y1 < pps->height)
2529
67.1k
            DUAL_TREE(x0, y1);
2530
89.7k
        if (x1 < pps->width && y1 < pps->height)
2531
67.1k
            DUAL_TREE(x1, y1);
2532
89.7k
    #undef DUAL_TREE
2533
938k
    } else {
2534
1.85M
        #define CODING_TREE(tree_type) do {                                             \
2535
1.85M
            const int qg_on_y = tree_type == DUAL_TREE_LUMA;                            \
2536
1.85M
            ret = hls_coding_tree(lc, x0, y0, cb_size, cb_size, qg_on_y, !qg_on_y,           \
2537
1.85M
                 cb_subdiv, cqt_depth, 0, 0, 0, SPLIT_NONE, tree_type, MODE_TYPE_ALL);  \
2538
1.85M
            if (ret < 0)                                                                \
2539
1.85M
                return ret;                                                             \
2540
1.85M
        } while (0)
2541
938k
        CODING_TREE(DUAL_TREE_LUMA);
2542
921k
        CODING_TREE(DUAL_TREE_CHROMA);
2543
921k
        #undef CODING_TREE
2544
921k
    }
2545
1.01M
    return 0;
2546
1.02M
}
2547
2548
4.32M
#define SET_SAO(elem, value)                            \
2549
4.32M
do {                                                    \
2550
3.91M
    if (!sao_merge_up_flag && !sao_merge_left_flag)     \
2551
3.91M
        sao->elem = value;                              \
2552
3.91M
    else if (sao_merge_left_flag)                       \
2553
632k
        sao->elem = CTB(fc->tab.sao, rx-1, ry).elem;         \
2554
632k
    else if (sao_merge_up_flag)                         \
2555
49.4k
        sao->elem = CTB(fc->tab.sao, rx, ry-1).elem;         \
2556
49.4k
    else                                                \
2557
49.4k
        sao->elem = 0;                                  \
2558
3.91M
} while (0)
2559
2560
static void hls_sao(VVCLocalContext *lc, const int rx, const int ry)
2561
1.61M
{
2562
1.61M
    VVCFrameContext *fc             = lc->fc;
2563
1.61M
    const H266RawSliceHeader *rsh   = lc->sc->sh.r;
2564
1.61M
    int sao_merge_left_flag         = 0;
2565
1.61M
    int sao_merge_up_flag           = 0;
2566
1.61M
    SAOParams *sao                  = &CTB(fc->tab.sao, rx, ry);
2567
1.61M
    int c_idx, i;
2568
2569
1.61M
    if (rsh->sh_sao_luma_used_flag || rsh->sh_sao_chroma_used_flag) {
2570
836k
        if (rx > 0) {
2571
70.3k
            if (lc->ctb_left_flag)
2572
70.3k
                sao_merge_left_flag = ff_vvc_sao_merge_flag_decode(lc);
2573
70.3k
        }
2574
836k
        if (ry > 0 && !sao_merge_left_flag) {
2575
8.79k
            if (lc->ctb_up_flag)
2576
8.79k
                sao_merge_up_flag = ff_vvc_sao_merge_flag_decode(lc);
2577
8.79k
        }
2578
836k
    }
2579
2580
6.41M
    for (c_idx = 0; c_idx < (fc->ps.sps->r->sps_chroma_format_idc ? 3 : 1); c_idx++) {
2581
4.80M
        const int sao_used_flag = !c_idx ? rsh->sh_sao_luma_used_flag : rsh->sh_sao_chroma_used_flag;
2582
4.80M
        if (!sao_used_flag) {
2583
2.32M
            sao->type_idx[c_idx] = SAO_NOT_APPLIED;
2584
2.32M
            continue;
2585
2.32M
        }
2586
2587
2.48M
        if (c_idx == 2) {
2588
824k
            sao->type_idx[2] = sao->type_idx[1];
2589
824k
            sao->eo_class[2] = sao->eo_class[1];
2590
1.65M
        } else {
2591
1.65M
            SET_SAO(type_idx[c_idx], ff_vvc_sao_type_idx_decode(lc));
2592
1.65M
        }
2593
2594
2.48M
        if (sao->type_idx[c_idx] == SAO_NOT_APPLIED)
2595
2.06M
            continue;
2596
2597
2.07M
        for (i = 0; i < 4; i++)
2598
1.66M
            SET_SAO(offset_abs[c_idx][i], ff_vvc_sao_offset_abs_decode(lc));
2599
2600
415k
        if (sao->type_idx[c_idx] == SAO_BAND) {
2601
887k
            for (i = 0; i < 4; i++) {
2602
709k
                if (sao->offset_abs[c_idx][i]) {
2603
279k
                    SET_SAO(offset_sign[c_idx][i],
2604
279k
                            ff_vvc_sao_offset_sign_decode(lc));
2605
430k
                } else {
2606
430k
                    sao->offset_sign[c_idx][i] = 0;
2607
430k
                }
2608
709k
            }
2609
177k
            SET_SAO(band_position[c_idx], ff_vvc_sao_band_position_decode(lc));
2610
238k
        } else if (c_idx != 2) {
2611
133k
            SET_SAO(eo_class[c_idx], ff_vvc_sao_eo_class_decode(lc));
2612
133k
        }
2613
2614
        // Inferred parameters
2615
415k
        sao->offset_val[c_idx][0] = 0;
2616
2.07M
        for (i = 0; i < 4; i++) {
2617
1.66M
            sao->offset_val[c_idx][i + 1] = sao->offset_abs[c_idx][i];
2618
1.66M
            if (sao->type_idx[c_idx] == SAO_EDGE) {
2619
953k
                if (i > 1)
2620
476k
                    sao->offset_val[c_idx][i + 1] = -sao->offset_val[c_idx][i + 1];
2621
953k
            } else if (sao->offset_sign[c_idx][i]) {
2622
149k
                sao->offset_val[c_idx][i + 1] = -sao->offset_val[c_idx][i + 1];
2623
149k
            }
2624
1.66M
            sao->offset_val[c_idx][i + 1] *= 1 << (fc->ps.sps->bit_depth - FFMIN(10, fc->ps.sps->bit_depth));
2625
1.66M
        }
2626
415k
    }
2627
1.61M
}
2628
2629
static void alf_params(VVCLocalContext *lc, const int rx, const int ry)
2630
1.61M
{
2631
1.61M
    const VVCFrameContext *fc     = lc->fc;
2632
1.61M
    const H266RawSliceHeader *sh  = lc->sc->sh.r;
2633
1.61M
    ALFParams *alf                = &CTB(fc->tab.alf, rx, ry);
2634
2635
1.61M
    alf->ctb_flag[LUMA] = alf->ctb_flag[CB] = alf->ctb_flag[CR] = 0;
2636
1.61M
    alf->ctb_cc_idc[0] = alf->ctb_cc_idc[1] = 0;
2637
1.61M
    if (sh->sh_alf_enabled_flag) {
2638
90.7k
        alf->ctb_flag[LUMA] = ff_vvc_alf_ctb_flag(lc, rx, ry, LUMA);
2639
90.7k
        if (alf->ctb_flag[LUMA]) {
2640
89.7k
            uint8_t alf_use_aps_flag = 0;
2641
89.7k
            if (sh->sh_num_alf_aps_ids_luma > 0)
2642
74.3k
                alf_use_aps_flag = ff_vvc_alf_use_aps_flag(lc);
2643
89.7k
            if (alf_use_aps_flag) {
2644
73.0k
                alf->ctb_filt_set_idx_y = 16;
2645
73.0k
                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
73.0k
            } else {
2648
16.7k
                alf->ctb_filt_set_idx_y = ff_vvc_alf_luma_fixed_filter_idx(lc);
2649
16.7k
            }
2650
89.7k
        }
2651
272k
        for (int c_idx = CB; c_idx <= CR; c_idx++) {
2652
181k
            const uint8_t alf_enabled_flag =
2653
181k
                c_idx == CB ? sh->sh_alf_cb_enabled_flag : sh->sh_alf_cr_enabled_flag;
2654
181k
            if (alf_enabled_flag) {
2655
150k
                const VVCALF *aps = fc->ps.alf_list[sh->sh_alf_aps_id_chroma];
2656
150k
                alf->ctb_flag[c_idx] = ff_vvc_alf_ctb_flag(lc, rx, ry, c_idx);
2657
150k
                alf->alf_ctb_filter_alt_idx[c_idx - 1] = 0;
2658
150k
                if (alf->ctb_flag[c_idx] && aps->num_chroma_filters > 1)
2659
35.6k
                    alf->alf_ctb_filter_alt_idx[c_idx - 1] = ff_vvc_alf_ctb_filter_alt_idx(lc, c_idx, aps->num_chroma_filters);
2660
150k
            }
2661
181k
        }
2662
90.7k
    }
2663
1.61M
    if (fc->ps.sps->r->sps_ccalf_enabled_flag) {
2664
770k
        const uint8_t cc_enabled[] = { sh->sh_alf_cc_cb_enabled_flag, sh->sh_alf_cc_cr_enabled_flag };
2665
770k
        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
75.2k
                const VVCALF *aps = fc->ps.alf_list[cc_aps_id[i]];
2669
75.2k
                alf->ctb_cc_idc[i] = ff_vvc_alf_ctb_cc_idc(lc, rx, ry, i, aps->num_cc_filters[i]);
2670
75.2k
            }
2671
1.54M
        }
2672
770k
    }
2673
1.61M
}
2674
2675
static void deblock_params(VVCLocalContext *lc, const int rx, const int ry)
2676
1.61M
{
2677
1.61M
    VVCFrameContext *fc = lc->fc;
2678
1.61M
    const VVCSH *sh     = &lc->sc->sh;
2679
1.61M
    CTB(fc->tab.deblock, rx, ry) = sh->deblock;
2680
1.61M
}
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.61M
{
2685
1.61M
    const VVCFrameContext *fc       = lc->fc;
2686
1.61M
    const VVCSPS *sps               = fc->ps.sps;
2687
1.61M
    const VVCPPS *pps               = fc->ps.pps;
2688
1.61M
    const VVCSH *sh                 = &lc->sc->sh;
2689
1.61M
    const H266RawSliceHeader *rsh   = sh->r;
2690
1.61M
    const unsigned int ctb_size     = sps->ctb_size_y;
2691
1.61M
    int ret                         = 0;
2692
2693
1.61M
    memset(lc->parse.chroma_qp_offset, 0, sizeof(lc->parse.chroma_qp_offset));
2694
2695
1.61M
    hls_sao(lc, x0 >> sps->ctb_log2_size_y, y0 >> sps->ctb_log2_size_y);
2696
1.61M
    alf_params(lc, x0 >> sps->ctb_log2_size_y, y0 >> sps->ctb_log2_size_y);
2697
1.61M
    deblock_params(lc, x0 >> sps->ctb_log2_size_y, y0 >> sps->ctb_log2_size_y);
2698
2699
1.61M
    if (IS_I(rsh) && sps->r->sps_qtbtt_dual_tree_intra_flag)
2700
728k
        ret = dual_tree_implicit_qt_split(lc, x0, y0, ctb_size, 0);
2701
882k
    else
2702
882k
        ret = hls_coding_tree(lc, x0, y0, ctb_size, ctb_size,
2703
882k
            1, 1, 0, 0, 0, 0, 0, SPLIT_NONE, SINGLE_TREE, MODE_TYPE_ALL);
2704
1.61M
    if (ret < 0)
2705
35.3k
        return ret;
2706
2707
1.57M
    if (rx == pps->ctb_to_col_bd[rx + 1] - 1) {
2708
1.50M
        if (ctu_idx == sh->num_ctus_in_curr_slice - 1) {
2709
1.50M
            const int end_of_slice_one_bit = ff_vvc_end_of_slice_flag_decode(lc);
2710
1.50M
            if (!end_of_slice_one_bit)
2711
1.40M
                return AVERROR_INVALIDDATA;
2712
1.50M
        } else {
2713
4.44k
            if (ry == pps->ctb_to_row_bd[ry + 1] - 1) {
2714
0
                const int end_of_tile_one_bit = ff_vvc_end_of_tile_one_bit(lc);
2715
0
                if (!end_of_tile_one_bit)
2716
0
                    return AVERROR_INVALIDDATA;
2717
4.44k
            } else {
2718
4.44k
                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
4.44k
            }
2724
4.44k
        }
2725
1.50M
    }
2726
2727
170k
    return 0;
2728
1.57M
}
2729
2730
static int has_inter_luma(const CodingUnit *cu)
2731
26.1k
{
2732
26.1k
    return cu->pred_mode != MODE_INTRA && cu->pred_mode != MODE_PLT && cu->tree_type != DUAL_TREE_CHROMA;
2733
26.1k
}
2734
2735
static int pred_get_y(const VVCLocalContext *lc, const int y0, const Mv *mv, const int height)
2736
24.1k
{
2737
24.1k
    const VVCPPS *pps = lc->fc->ps.pps;
2738
24.1k
    const int idx     = lc->sc->sh.r->curr_subpic_idx;
2739
24.1k
    const int top     = pps->subpic_y[idx];
2740
24.1k
    const int bottom  = top + pps->subpic_height[idx];
2741
2742
24.1k
    return av_clip(y0 + (mv->y >> 4) + height, top, bottom);
2743
24.1k
}
2744
2745
static void cu_get_max_y(const CodingUnit *cu, int max_y[2][VVC_MAX_REF_ENTRIES], const VVCLocalContext *lc)
2746
19.6k
{
2747
19.6k
    const VVCFrameContext *fc   = lc->fc;
2748
19.6k
    const PredictionUnit *pu    = &cu->pu;
2749
2750
19.6k
    if (pu->merge_gpm_flag) {
2751
3.61k
        for (int i = 0; i < FF_ARRAY_ELEMS(pu->gpm_mv); i++) {
2752
2.41k
            const MvField *mvf  = pu->gpm_mv + i;
2753
2.41k
            const int lx        = mvf->pred_flag - PF_L0;
2754
2.41k
            const int idx       = mvf->ref_idx[lx];
2755
2.41k
            const int y         = pred_get_y(lc, cu->y0, mvf->mv + lx, cu->cb_height);
2756
2757
2.41k
            max_y[lx][idx]      = FFMAX(max_y[lx][idx], y);
2758
2.41k
        }
2759
18.4k
    } else {
2760
18.4k
        const MotionInfo *mi    = &pu->mi;
2761
18.4k
        const int max_dmvr_off  = (!pu->inter_affine_flag && pu->dmvr_flag) ? 2 : 0;
2762
18.4k
        const int sbw           = cu->cb_width / mi->num_sb_x;
2763
18.4k
        const int sbh           = cu->cb_height / mi->num_sb_y;
2764
37.1k
        for (int sby = 0; sby < mi->num_sb_y; sby++) {
2765
38.0k
            for (int sbx = 0; sbx < mi->num_sb_x; sbx++) {
2766
19.3k
                const int x0        = cu->x0 + sbx * sbw;
2767
19.3k
                const int y0        = cu->y0 + sby * sbh;
2768
19.3k
                const MvField *mvf  = ff_vvc_get_mvf(fc, x0, y0);
2769
57.9k
                for (int lx = 0; lx < 2; lx++) {
2770
38.6k
                    const PredFlag mask = 1 << lx;
2771
38.6k
                    if (mvf->pred_flag & mask) {
2772
21.7k
                        const int idx   = mvf->ref_idx[lx];
2773
21.7k
                        const int y     = pred_get_y(lc, y0, mvf->mv + lx, sbh);
2774
2775
21.7k
                        max_y[lx][idx]  = FFMAX(max_y[lx][idx], y + max_dmvr_off);
2776
21.7k
                    }
2777
38.6k
                }
2778
19.3k
            }
2779
18.7k
        }
2780
18.4k
    }
2781
19.6k
}
2782
2783
static void ctu_get_pred(VVCLocalContext *lc, const int rs)
2784
170k
{
2785
170k
    const VVCFrameContext *fc       = lc->fc;
2786
170k
    const H266RawSliceHeader *rsh   = lc->sc->sh.r;
2787
170k
    CTU *ctu                        = fc->tab.ctus + rs;
2788
170k
    const CodingUnit *cu            = fc->tab.cus[rs];
2789
2790
170k
    ctu->has_dmvr = 0;
2791
2792
170k
    if (IS_I(rsh))
2793
151k
        return;
2794
2795
56.5k
    for (int lx = 0; lx < 2; lx++)
2796
37.6k
        memset(ctu->max_y[lx], -1, sizeof(ctu->max_y[0][0]) * rsh->num_ref_idx_active[lx]);
2797
2798
45.0k
    while (cu) {
2799
26.1k
        if (has_inter_luma(cu)) {
2800
19.6k
            cu_get_max_y(cu, ctu->max_y, lc);
2801
19.6k
            ctu->has_dmvr |= cu->pu.dmvr_flag;
2802
19.6k
        }
2803
26.1k
        cu = cu->next;
2804
26.1k
    }
2805
18.8k
    ctu->max_y_idx[0] = ctu->max_y_idx[1] = 0;
2806
18.8k
}
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.61M
{
2811
1.61M
    const VVCFrameContext *fc   = lc->fc;
2812
1.61M
    const VVCSPS *sps           = fc->ps.sps;
2813
1.61M
    const VVCPPS *pps           = fc->ps.pps;
2814
1.61M
    const int x_ctb             = rx << sps->ctb_log2_size_y;
2815
1.61M
    const int y_ctb             = ry << sps->ctb_log2_size_y;
2816
1.61M
    const int ctb_size          = 1 << sps->ctb_log2_size_y << sps->ctb_log2_size_y;
2817
1.61M
    EntryPoint* ep              = lc->ep;
2818
1.61M
    int ret;
2819
2820
1.61M
    if (rx == pps->ctb_to_col_bd[rx]) {
2821
1.54M
        ep->num_hmvp = 0;
2822
1.54M
        ep->num_hmvp_ibc = 0;
2823
1.54M
        ep->is_first_qg = ry == pps->ctb_to_row_bd[ry] || !ctu_idx;
2824
1.54M
    }
2825
2826
1.61M
    lc->coeffs = fc->tab.coeffs + rs * ctb_size * VVC_MAX_SAMPLE_ARRAYS;
2827
1.61M
    lc->cu     = NULL;
2828
2829
1.61M
    ff_vvc_cabac_init(lc, ctu_idx, rx, ry);
2830
1.61M
    ff_vvc_decode_neighbour(lc, x_ctb, y_ctb, rx, ry, rs);
2831
1.61M
    ret = hls_coding_tree_unit(lc, x_ctb, y_ctb, ctu_idx, rx, ry);
2832
1.61M
    if (ret < 0)
2833
1.44M
        return ret;
2834
170k
    ctu_get_pred(lc, rs);
2835
2836
170k
    return 0;
2837
1.61M
}
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.24M
{
2842
2.24M
    VVCFrameContext *fc = lc->fc;
2843
2.24M
    const int ctb_size         = fc->ps.sps->ctb_size_y;
2844
2845
2.24M
    lc->end_of_tiles_x = fc->ps.pps->width;
2846
2.24M
    lc->end_of_tiles_y = fc->ps.pps->height;
2847
2.24M
    if (fc->ps.pps->ctb_to_col_bd[rx] != fc->ps.pps->ctb_to_col_bd[rx + 1])
2848
2.00M
        lc->end_of_tiles_x = FFMIN(x_ctb + ctb_size, lc->end_of_tiles_x);
2849
2.24M
    if (fc->ps.pps->ctb_to_row_bd[ry] != fc->ps.pps->ctb_to_row_bd[ry + 1])
2850
2.02M
        lc->end_of_tiles_y = FFMIN(y_ctb + ctb_size, lc->end_of_tiles_y);
2851
2852
2.24M
    lc->boundary_flags = 0;
2853
2.24M
    if (rx > 0 && fc->ps.pps->ctb_to_col_bd[rx] != fc->ps.pps->ctb_to_col_bd[rx - 1])
2854
0
        lc->boundary_flags |= BOUNDARY_LEFT_TILE;
2855
2.24M
    if (rx > 0 && fc->tab.slice_idx[rs] != fc->tab.slice_idx[rs - 1])
2856
0
        lc->boundary_flags |= BOUNDARY_LEFT_SLICE;
2857
2.24M
    if (ry > 0 && fc->ps.pps->ctb_to_row_bd[ry] != fc->ps.pps->ctb_to_row_bd[ry - 1])
2858
0
        lc->boundary_flags |= BOUNDARY_UPPER_TILE;
2859
2.24M
    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.24M
    if (fc->ps.sps->r->sps_subpic_ctu_top_left_x[lc->sc->sh.r->curr_subpic_idx] == rx)
2862
2.01M
        lc->boundary_flags |= BOUNDARY_LEFT_SUBPIC;
2863
2.24M
    if (fc->ps.sps->r->sps_subpic_ctu_top_left_y[lc->sc->sh.r->curr_subpic_idx] == ry)
2864
2.02M
        lc->boundary_flags |= BOUNDARY_UPPER_SUBPIC;
2865
2.24M
    lc->ctb_left_flag = rx > 0 && !(lc->boundary_flags & BOUNDARY_LEFT_TILE);
2866
2.24M
    lc->ctb_up_flag   = ry > 0 && !(lc->boundary_flags & BOUNDARY_UPPER_TILE) && !(lc->boundary_flags & BOUNDARY_UPPER_SLICE);
2867
2.24M
    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
206k
        (fc->ps.pps->ctb_to_row_bd[ry] == fc->ps.pps->ctb_to_row_bd[ry - 1]);
2869
2.24M
    lc->ctb_up_left_flag = lc->ctb_left_flag && lc->ctb_up_flag;
2870
2.24M
}
2871
2872
void ff_vvc_set_neighbour_available(VVCLocalContext *lc,
2873
    const int x0, const int y0, const int w, const int h)
2874
12.3M
{
2875
12.3M
    const int log2_ctb_size = lc->fc->ps.sps->ctb_log2_size_y;
2876
12.3M
    const int x0b = av_zero_extend(x0, log2_ctb_size);
2877
12.3M
    const int y0b = av_zero_extend(y0, log2_ctb_size);
2878
2879
12.3M
    lc->na.cand_up       = (lc->ctb_up_flag   || y0b);
2880
12.3M
    lc->na.cand_left     = (lc->ctb_left_flag || x0b);
2881
12.3M
    lc->na.cand_up_left  = (x0b || y0b) ? lc->na.cand_left && lc->na.cand_up : lc->ctb_up_left_flag;
2882
12.3M
    lc->na.cand_up_right_sap =
2883
12.3M
            (x0b + w == 1 << log2_ctb_size) ? lc->ctb_up_right_flag && !y0b : lc->na.cand_up;
2884
12.3M
    lc->na.cand_up_right = lc->na.cand_up_right_sap && (x0 + w) < lc->end_of_tiles_x;
2885
12.3M
}
2886
2887
void ff_vvc_ctu_free_cus(CodingUnit **cus)
2888
2.82M
{
2889
11.3M
    while (*cus) {
2890
8.52M
        CodingUnit *cu          = *cus;
2891
8.52M
        TransformUnit **head    = &cu->tus.head;
2892
2893
8.52M
        *cus = cu->next;
2894
2895
17.1M
        while (*head) {
2896
8.66M
            TransformUnit *tu = *head;
2897
8.66M
            *head = tu->next;
2898
8.66M
            av_refstruct_unref(&tu);
2899
8.66M
        }
2900
8.52M
        cu->tus.tail = NULL;
2901
2902
8.52M
        av_refstruct_unref(&cu);
2903
8.52M
    }
2904
2.82M
}
2905
2906
int ff_vvc_get_qPy(const VVCFrameContext *fc, const int xc, const int yc)
2907
11.2M
{
2908
11.2M
    const int min_cb_log2_size_y = fc->ps.sps->min_cb_log2_size_y;
2909
11.2M
    const int x                  = xc >> min_cb_log2_size_y;
2910
11.2M
    const int y                  = yc >> min_cb_log2_size_y;
2911
11.2M
    return fc->tab.qp[LUMA][x + y * fc->ps.pps->min_cb_width];
2912
11.2M
}
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.53M
{
2917
6.14M
    for (size_t i = 0; i < FF_ARRAY_ELEMS(ep->stat_coeff); ++i) {
2918
4.60M
        ep->stat_coeff[i] =
2919
4.60M
            persistent_rice_adaptation_enabled_flag ? 2 * (av_log2(bit_depth - 10)) : 0;
2920
4.60M
    }
2921
1.53M
}
2922
2923
void ff_vvc_channel_range(int *start, int *end, const VVCTreeType tree_type, const uint8_t chroma_format_idc)
2924
527k
{
2925
527k
    const bool has_chroma = chroma_format_idc && tree_type != DUAL_TREE_LUMA;
2926
527k
    const bool has_luma   = tree_type != DUAL_TREE_CHROMA;
2927
2928
527k
    *start = has_luma   ? LUMA : CB;
2929
527k
    *end   = has_chroma ? VVC_MAX_SAMPLE_ARRAYS : CB;
2930
527k
}