FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/vvc/dec.c
Date: 2024-10-27 21:33:06
Exec Total Coverage
Lines: 579 650 89.1%
Functions: 50 50 100.0%
Branches: 349 476 73.3%

Line Branch Exec Source
1 /*
2 * VVC video decoder
3 *
4 * Copyright (C) 2021 Nuo Mi
5 * Copyright (C) 2022 Xu Mu
6 *
7 * This file is part of FFmpeg.
8 *
9 * FFmpeg is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * FFmpeg is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with FFmpeg; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23 #include "libavcodec/codec_internal.h"
24 #include "libavcodec/decode.h"
25 #include "libavcodec/profiles.h"
26 #include "libavcodec/refstruct.h"
27 #include "libavutil/cpu.h"
28 #include "libavutil/mem.h"
29 #include "libavutil/thread.h"
30
31 #include "dec.h"
32 #include "ctu.h"
33 #include "data.h"
34 #include "refs.h"
35 #include "thread.h"
36
37 #define TAB_MAX 32
38
39 typedef struct Tab {
40 void **tab;
41 size_t size;
42 } Tab;
43
44 typedef struct TabList {
45 Tab tabs[TAB_MAX];
46 int nb_tabs;
47
48 int zero;
49 int realloc;
50 } TabList;
51
52 #define TL_ADD(t, s) do { \
53 av_assert0(l->nb_tabs < TAB_MAX); \
54 l->tabs[l->nb_tabs].tab = (void**)&fc->tab.t; \
55 l->tabs[l->nb_tabs].size = sizeof(*fc->tab.t) * (s); \
56 l->nb_tabs++; \
57 } while (0)
58
59 26950 static void tl_init(TabList *l, const int zero, const int realloc)
60 {
61 26950 l->nb_tabs = 0;
62 26950 l->zero = zero;
63 26950 l->realloc = realloc;
64 26950 }
65
66 10315 static int tl_free(TabList *l)
67 {
68
2/2
✓ Branch 0 taken 64457 times.
✓ Branch 1 taken 10315 times.
74772 for (int i = 0; i < l->nb_tabs; i++)
69 64457 av_freep(l->tabs[i].tab);
70
71 10315 return 0;
72 }
73
74 9955 static int tl_create(TabList *l)
75 {
76
2/2
✓ Branch 0 taken 3275 times.
✓ Branch 1 taken 6680 times.
9955 if (l->realloc) {
77 3275 tl_free(l);
78
79
2/2
✓ Branch 0 taken 20133 times.
✓ Branch 1 taken 3275 times.
23408 for (int i = 0; i < l->nb_tabs; i++) {
80 20133 Tab *t = l->tabs + i;
81
2/2
✓ Branch 0 taken 4320 times.
✓ Branch 1 taken 15813 times.
20133 *t->tab = l->zero ? av_mallocz(t->size) : av_malloc(t->size);
82
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 20133 times.
20133 if (!*t->tab)
83 return AVERROR(ENOMEM);
84 }
85 }
86 9955 return 0;
87 }
88
89 9955 static int tl_zero(TabList *l)
90 {
91
2/2
✓ Branch 0 taken 4543 times.
✓ Branch 1 taken 5412 times.
9955 if (l->zero) {
92
2/2
✓ Branch 0 taken 16344 times.
✓ Branch 1 taken 4543 times.
20887 for (int i = 0; i < l->nb_tabs; i++) {
93 16344 Tab *t = l->tabs + i;
94 16344 memset(*t->tab, 0, t->size);
95 }
96 }
97 9955 return 0;
98 }
99
100 2450 static void ctu_nz_tl_init(TabList *l, VVCFrameContext *fc)
101 {
102 2450 const VVCSPS *sps = fc->ps.sps;
103 2450 const VVCPPS *pps = fc->ps.pps;
104
2/2
✓ Branch 0 taken 2047 times.
✓ Branch 1 taken 403 times.
2450 const int ctu_size = sps ? (1 << sps->ctb_log2_size_y << sps->ctb_log2_size_y) : 0;
105
2/2
✓ Branch 0 taken 2047 times.
✓ Branch 1 taken 403 times.
2450 const int ctu_count = pps ? pps->ctb_count : 0;
106
3/4
✓ Branch 0 taken 2213 times.
✓ Branch 1 taken 237 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2213 times.
2450 const int changed = fc->tab.sz.ctu_count != ctu_count || fc->tab.sz.ctu_size != ctu_size;
107
108 2450 tl_init(l, 0, changed);
109
110
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2450 times.
2450 TL_ADD(cus, ctu_count);
111
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2450 times.
2450 TL_ADD(ctus, ctu_count);
112
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2450 times.
2450 TL_ADD(deblock, ctu_count);
113
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2450 times.
2450 TL_ADD(sao, ctu_count);
114
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2450 times.
2450 TL_ADD(alf, ctu_count);
115
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2450 times.
2450 TL_ADD(slice_idx, ctu_count);
116
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2450 times.
2450 TL_ADD(coeffs, ctu_count * ctu_size * VVC_MAX_SAMPLE_ARRAYS);
117 2450 }
118
119 2450 static void min_cb_tl_init(TabList *l, VVCFrameContext *fc)
120 {
121 2450 const VVCPPS *pps = fc->ps.pps;
122
2/2
✓ Branch 0 taken 2047 times.
✓ Branch 1 taken 403 times.
2450 const int pic_size_in_min_cb = pps ? pps->min_cb_width * pps->min_cb_height : 0;
123 2450 const int changed = fc->tab.sz.pic_size_in_min_cb != pic_size_in_min_cb;
124
125 2450 tl_init(l, 1, changed);
126
127
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2450 times.
2450 TL_ADD(imf, pic_size_in_min_cb);
128
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2450 times.
2450 TL_ADD(imm, pic_size_in_min_cb);
129
130
2/2
✓ Branch 0 taken 4900 times.
✓ Branch 1 taken 2450 times.
7350 for (int i = LUMA; i <= CHROMA; i++)
131
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4900 times.
4900 TL_ADD(cb_width[i], pic_size_in_min_cb); //is_a0_available requires this
132 2450 }
133
134 2450 static void min_cb_nz_tl_init(TabList *l, VVCFrameContext *fc)
135 {
136 2450 const VVCPPS *pps = fc->ps.pps;
137
2/2
✓ Branch 0 taken 2047 times.
✓ Branch 1 taken 403 times.
2450 const int pic_size_in_min_cb = pps ? pps->min_cb_width * pps->min_cb_height : 0;
138 2450 const int changed = fc->tab.sz.pic_size_in_min_cb != pic_size_in_min_cb;
139
140 2450 tl_init(l, 0, changed);
141
142
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2450 times.
2450 TL_ADD(skip, pic_size_in_min_cb);
143
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2450 times.
2450 TL_ADD(imtf, pic_size_in_min_cb);
144
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2450 times.
2450 TL_ADD(ipm, pic_size_in_min_cb);
145
146
2/2
✓ Branch 0 taken 4900 times.
✓ Branch 1 taken 2450 times.
7350 for (int i = LUMA; i <= CHROMA; i++) {
147
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4900 times.
4900 TL_ADD(cqt_depth[i], pic_size_in_min_cb);
148
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4900 times.
4900 TL_ADD(cb_pos_x[i], pic_size_in_min_cb);
149
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4900 times.
4900 TL_ADD(cb_pos_y[i], pic_size_in_min_cb);
150
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4900 times.
4900 TL_ADD(cb_height[i], pic_size_in_min_cb);
151
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4900 times.
4900 TL_ADD(cp_mv[i], pic_size_in_min_cb * MAX_CONTROL_POINTS);
152
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4900 times.
4900 TL_ADD(cpm[i], pic_size_in_min_cb);
153
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4900 times.
4900 TL_ADD(pcmf[i], pic_size_in_min_cb);
154 }
155 // For luma, qp can only change at the CU level, so the qp tab size is related to the CU.
156
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2450 times.
2450 TL_ADD(qp[LUMA], pic_size_in_min_cb);
157 2450 }
158
159 2450 static void min_pu_tl_init(TabList *l, VVCFrameContext *fc)
160 {
161 2450 const VVCPPS *pps = fc->ps.pps;
162
2/2
✓ Branch 0 taken 2047 times.
✓ Branch 1 taken 403 times.
2450 const int pic_size_in_min_pu = pps ? pps->min_pu_width * pps->min_pu_height : 0;
163 2450 const int changed = fc->tab.sz.pic_size_in_min_pu != pic_size_in_min_pu;
164
165 2450 tl_init(l, 1, changed);
166
167
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2450 times.
2450 TL_ADD(iaf, pic_size_in_min_pu);
168 2450 }
169
170 2450 static void min_pu_nz_tl_init(TabList *l, VVCFrameContext *fc)
171 {
172 2450 const VVCPPS *pps = fc->ps.pps;
173
2/2
✓ Branch 0 taken 2047 times.
✓ Branch 1 taken 403 times.
2450 const int pic_size_in_min_pu = pps ? pps->min_pu_width * pps->min_pu_height : 0;
174 2450 const int changed = fc->tab.sz.pic_size_in_min_pu != pic_size_in_min_pu;
175
176 2450 tl_init(l, 0, changed);
177
178
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2450 times.
2450 TL_ADD(msf, pic_size_in_min_pu);
179
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2450 times.
2450 TL_ADD(mmi, pic_size_in_min_pu);
180
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2450 times.
2450 TL_ADD(mvf, pic_size_in_min_pu);
181 2450 }
182
183 2450 static void min_tu_tl_init(TabList *l, VVCFrameContext *fc)
184 {
185 2450 const VVCPPS *pps = fc->ps.pps;
186
2/2
✓ Branch 0 taken 2047 times.
✓ Branch 1 taken 403 times.
2450 const int pic_size_in_min_tu = pps ? pps->min_tu_width * pps->min_tu_height : 0;
187 2450 const int changed = fc->tab.sz.pic_size_in_min_tu != pic_size_in_min_tu;
188
189 2450 tl_init(l, 1, changed);
190
191
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2450 times.
2450 TL_ADD(tu_joint_cbcr_residual_flag, pic_size_in_min_tu);
192
193
2/2
✓ Branch 0 taken 7350 times.
✓ Branch 1 taken 2450 times.
9800 for (int i = 0; i < VVC_MAX_SAMPLE_ARRAYS; i++) {
194
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7350 times.
7350 TL_ADD(tu_coded_flag[i], pic_size_in_min_tu);
195
196
2/2
✓ Branch 0 taken 14700 times.
✓ Branch 1 taken 7350 times.
22050 for (int vertical = 0; vertical < 2; vertical++)
197
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14700 times.
14700 TL_ADD(bs[vertical][i], pic_size_in_min_tu);
198 }
199 2450 }
200
201 2450 static void min_tu_nz_tl_init(TabList *l, VVCFrameContext *fc)
202 {
203 2450 const VVCPPS *pps = fc->ps.pps;
204
2/2
✓ Branch 0 taken 2047 times.
✓ Branch 1 taken 403 times.
2450 const int pic_size_in_min_tu = pps ? pps->min_tu_width * pps->min_tu_height : 0;
205 2450 const int changed = fc->tab.sz.pic_size_in_min_tu != pic_size_in_min_tu;
206
207 2450 tl_init(l, 0, changed);
208
209
2/2
✓ Branch 0 taken 4900 times.
✓ Branch 1 taken 2450 times.
7350 for (int i = LUMA; i <= CHROMA; i++) {
210
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4900 times.
4900 TL_ADD(tb_width[i], pic_size_in_min_tu);
211
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4900 times.
4900 TL_ADD(tb_height[i], pic_size_in_min_tu);
212 }
213
214
2/2
✓ Branch 0 taken 4900 times.
✓ Branch 1 taken 2450 times.
7350 for (int vertical = 0; vertical < 2; vertical++) {
215
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4900 times.
4900 TL_ADD(max_len_p[vertical], pic_size_in_min_tu);
216
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4900 times.
4900 TL_ADD(max_len_q[vertical], pic_size_in_min_tu);
217 }
218
219 // For chroma, considering the joint CbCr, the QP tab size is related to the TU.
220
2/2
✓ Branch 0 taken 4900 times.
✓ Branch 1 taken 2450 times.
7350 for (int i = CB; i < VVC_MAX_SAMPLE_ARRAYS; i++)
221
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4900 times.
4900 TL_ADD(qp[i], pic_size_in_min_tu);
222 2450 }
223
224 2450 static void pixel_buffer_nz_tl_init(TabList *l, VVCFrameContext *fc)
225 {
226 2450 const VVCSPS *sps = fc->ps.sps;
227 2450 const VVCPPS *pps = fc->ps.pps;
228
2/2
✓ Branch 0 taken 2047 times.
✓ Branch 1 taken 403 times.
2450 const int width = pps ? pps->width : 0;
229
2/2
✓ Branch 0 taken 2047 times.
✓ Branch 1 taken 403 times.
2450 const int height = pps ? pps->height : 0;
230
2/2
✓ Branch 0 taken 2047 times.
✓ Branch 1 taken 403 times.
2450 const int ctu_width = pps ? pps->ctb_width : 0;
231
2/2
✓ Branch 0 taken 2047 times.
✓ Branch 1 taken 403 times.
2450 const int ctu_height = pps ? pps->ctb_height : 0;
232
2/2
✓ Branch 0 taken 2047 times.
✓ Branch 1 taken 403 times.
2450 const int chroma_idc = sps ? sps->r->sps_chroma_format_idc : 0;
233
2/2
✓ Branch 0 taken 2047 times.
✓ Branch 1 taken 403 times.
2450 const int ps = sps ? sps->pixel_shift : 0;
234
2/2
✓ Branch 0 taken 1905 times.
✓ Branch 1 taken 545 times.
2450 const int c_end = chroma_idc ? VVC_MAX_SAMPLE_ARRAYS : 1;
235 7123 const int changed = fc->tab.sz.chroma_format_idc != chroma_idc ||
236
3/4
✓ Branch 0 taken 2213 times.
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 2213 times.
✗ Branch 3 not taken.
2223 fc->tab.sz.width != width || fc->tab.sz.height != height ||
237
4/6
✓ Branch 0 taken 2223 times.
✓ Branch 1 taken 227 times.
✓ Branch 2 taken 2213 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2213 times.
✗ Branch 5 not taken.
6886 fc->tab.sz.ctu_width != ctu_width || fc->tab.sz.ctu_height != ctu_height ||
238
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2213 times.
2213 fc->tab.sz.pixel_shift != ps;
239
240 2450 tl_init(l, 0, changed);
241
242
2/2
✓ Branch 0 taken 6260 times.
✓ Branch 1 taken 2450 times.
8710 for (int c_idx = 0; c_idx < c_end; c_idx++) {
243
2/2
✓ Branch 0 taken 5857 times.
✓ Branch 1 taken 403 times.
6260 const int w = width >> (sps ? sps->hshift[c_idx] : 0);
244
2/2
✓ Branch 0 taken 5857 times.
✓ Branch 1 taken 403 times.
6260 const int h = height >> (sps ? sps->vshift[c_idx] : 0);
245
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6260 times.
6260 TL_ADD(sao_pixel_buffer_h[c_idx], (w * 2 * ctu_height) << ps);
246
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6260 times.
6260 TL_ADD(sao_pixel_buffer_v[c_idx], (h * 2 * ctu_width) << ps);
247 }
248
249
2/2
✓ Branch 0 taken 6260 times.
✓ Branch 1 taken 2450 times.
8710 for (int c_idx = 0; c_idx < c_end; c_idx++) {
250
2/2
✓ Branch 0 taken 5857 times.
✓ Branch 1 taken 403 times.
6260 const int w = width >> (sps ? sps->hshift[c_idx] : 0);
251
2/2
✓ Branch 0 taken 5857 times.
✓ Branch 1 taken 403 times.
6260 const int h = height >> (sps ? sps->vshift[c_idx] : 0);
252
2/2
✓ Branch 0 taken 3810 times.
✓ Branch 1 taken 2450 times.
6260 const int border_pixels = c_idx ? ALF_BORDER_CHROMA : ALF_BORDER_LUMA;
253
2/2
✓ Branch 0 taken 12520 times.
✓ Branch 1 taken 6260 times.
18780 for (int i = 0; i < 2; i++) {
254
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12520 times.
12520 TL_ADD(alf_pixel_buffer_h[c_idx][i], (w * border_pixels * ctu_height) << ps);
255
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12520 times.
12520 TL_ADD(alf_pixel_buffer_v[c_idx][i], h * ALF_PADDING_SIZE * ctu_width);
256 }
257 }
258 2450 }
259
260 2450 static void msm_tl_init(TabList *l, VVCFrameContext *fc)
261 {
262 2450 const VVCPPS *pps = fc->ps.pps;
263
2/2
✓ Branch 0 taken 2047 times.
✓ Branch 1 taken 403 times.
2450 const int w32 = pps ? AV_CEIL_RSHIFT(pps->width, 5) : 0;
264
2/2
✓ Branch 0 taken 2047 times.
✓ Branch 1 taken 403 times.
2450 const int h32 = pps ? AV_CEIL_RSHIFT(pps->height, 5) : 0;
265
2/2
✓ Branch 0 taken 2213 times.
✓ Branch 1 taken 237 times.
4663 const int changed = AV_CEIL_RSHIFT(fc->tab.sz.width, 5) != w32 ||
266
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2213 times.
2213 AV_CEIL_RSHIFT(fc->tab.sz.height, 5) != h32;
267
268 2450 tl_init(l, 1, changed);
269
270
2/2
✓ Branch 0 taken 4900 times.
✓ Branch 1 taken 2450 times.
7350 for (int i = LUMA; i <= CHROMA; i++)
271
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4900 times.
4900 TL_ADD(msm[i], w32 * h32);
272 2450 }
273
274 2450 static void ispmf_tl_init(TabList *l, VVCFrameContext *fc)
275 {
276 2450 const VVCPPS *pps = fc->ps.pps;
277
2/2
✓ Branch 0 taken 2047 times.
✓ Branch 1 taken 403 times.
2450 const int w64 = pps ? AV_CEIL_RSHIFT(pps->width, 6) : 0;
278
2/2
✓ Branch 0 taken 2047 times.
✓ Branch 1 taken 403 times.
2450 const int h64 = pps ? AV_CEIL_RSHIFT(pps->height, 6) : 0;
279
2/2
✓ Branch 0 taken 2213 times.
✓ Branch 1 taken 237 times.
4663 const int changed = AV_CEIL_RSHIFT(fc->tab.sz.width, 6) != w64 ||
280
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2213 times.
2213 AV_CEIL_RSHIFT(fc->tab.sz.height, 6) != h64;
281
282 2450 tl_init(l, 1, changed);
283
284
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2450 times.
2450 TL_ADD(ispmf, w64 * h64);
285 2450 }
286
287 2450 static void ibc_tl_init(TabList *l, VVCFrameContext *fc)
288 {
289 2450 const VVCSPS *sps = fc->ps.sps;
290 2450 const VVCPPS *pps = fc->ps.pps;
291
2/2
✓ Branch 0 taken 2047 times.
✓ Branch 1 taken 403 times.
2450 const int ctu_height = pps ? pps->ctb_height : 0;
292
2/2
✓ Branch 0 taken 2047 times.
✓ Branch 1 taken 403 times.
2450 const int ctu_size = sps ? sps->ctb_size_y : 0;
293
2/2
✓ Branch 0 taken 2047 times.
✓ Branch 1 taken 403 times.
2450 const int ps = sps ? sps->pixel_shift : 0;
294
2/2
✓ Branch 0 taken 2047 times.
✓ Branch 1 taken 403 times.
2450 const int chroma_idc = sps ? sps->r->sps_chroma_format_idc : 0;
295
2/2
✓ Branch 0 taken 2047 times.
✓ Branch 1 taken 403 times.
2450 const int has_ibc = sps ? sps->r->sps_ibc_enabled_flag : 0;
296 7123 const int changed = fc->tab.sz.chroma_format_idc != chroma_idc ||
297
2/2
✓ Branch 0 taken 2213 times.
✓ Branch 1 taken 10 times.
2223 fc->tab.sz.ctu_height != ctu_height ||
298
4/4
✓ Branch 0 taken 2223 times.
✓ Branch 1 taken 227 times.
✓ Branch 2 taken 403 times.
✓ Branch 3 taken 1810 times.
5076 fc->tab.sz.ctu_size != ctu_size ||
299
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 403 times.
403 fc->tab.sz.pixel_shift != ps;
300
301
2/2
✓ Branch 0 taken 2047 times.
✓ Branch 1 taken 403 times.
2450 fc->tab.sz.ibc_buffer_width = ctu_size ? 2 * MAX_CTU_SIZE * MAX_CTU_SIZE / ctu_size : 0;
302
303 2450 tl_init(l, has_ibc, changed);
304
305
2/2
✓ Branch 0 taken 7350 times.
✓ Branch 1 taken 2450 times.
9800 for (int i = LUMA; i < VVC_MAX_SAMPLE_ARRAYS; i++) {
306
2/2
✓ Branch 0 taken 6141 times.
✓ Branch 1 taken 1209 times.
7350 const int hs = sps ? sps->hshift[i] : 0;
307
2/2
✓ Branch 0 taken 6141 times.
✓ Branch 1 taken 1209 times.
7350 const int vs = sps ? sps->vshift[i] : 0;
308
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7350 times.
7350 TL_ADD(ibc_vir_buf[i], fc->tab.sz.ibc_buffer_width * ctu_size * ctu_height << ps >> hs >> vs);
309 }
310 2450 }
311
312 typedef void (*tl_init_fn)(TabList *l, VVCFrameContext *fc);
313
314 2450 static int frame_context_for_each_tl(VVCFrameContext *fc, int (*unary_fn)(TabList *l))
315 {
316 2450 const tl_init_fn init[] = {
317 ctu_nz_tl_init,
318 min_cb_tl_init,
319 min_cb_nz_tl_init,
320 min_pu_tl_init,
321 min_pu_nz_tl_init,
322 min_tu_tl_init,
323 min_tu_nz_tl_init,
324 pixel_buffer_nz_tl_init,
325 msm_tl_init,
326 ispmf_tl_init,
327 ibc_tl_init,
328 };
329
330
2/2
✓ Branch 0 taken 26950 times.
✓ Branch 1 taken 2450 times.
29400 for (int i = 0; i < FF_ARRAY_ELEMS(init); i++) {
331 TabList l;
332 int ret;
333
334 26950 init[i](&l, fc);
335 26950 ret = unary_fn(&l);
336
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26950 times.
26950 if (ret < 0)
337 return ret;
338 }
339 2450 return 0;
340 }
341
342 1545 static void free_cus(VVCFrameContext *fc)
343 {
344
2/2
✓ Branch 0 taken 905 times.
✓ Branch 1 taken 640 times.
1545 if (fc->tab.cus) {
345
2/2
✓ Branch 0 taken 44552 times.
✓ Branch 1 taken 905 times.
45457 for (int i = 0; i < fc->tab.sz.ctu_count; i++)
346 44552 ff_vvc_ctu_free_cus(fc->tab.cus + i);
347 }
348 1545 }
349
350 640 static void pic_arrays_free(VVCFrameContext *fc)
351 {
352 640 free_cus(fc);
353 640 frame_context_for_each_tl(fc, tl_free);
354 640 ff_refstruct_pool_uninit(&fc->rpl_tab_pool);
355 640 ff_refstruct_pool_uninit(&fc->tab_dmvr_mvf_pool);
356
357 640 memset(&fc->tab.sz, 0, sizeof(fc->tab.sz));
358 640 }
359
360 905 static int pic_arrays_init(VVCContext *s, VVCFrameContext *fc)
361 {
362 905 const VVCSPS *sps = fc->ps.sps;
363 905 const VVCPPS *pps = fc->ps.pps;
364 905 const int ctu_count = pps->ctb_count;
365 905 const int pic_size_in_min_pu = pps->min_pu_width * pps->min_pu_height;
366 int ret;
367
368 905 free_cus(fc);
369
370 905 ret = frame_context_for_each_tl(fc, tl_create);
371
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 905 times.
905 if (ret < 0)
372 return ret;
373
374 // for error handling case, we may call free_cus before VVC_TASK_STAGE_INIT, so we need to set cus to 0 here
375 905 memset(fc->tab.cus, 0, sizeof(*fc->tab.cus) * ctu_count);
376
377 905 memset(fc->tab.slice_idx, -1, sizeof(*fc->tab.slice_idx) * ctu_count);
378
379
2/2
✓ Branch 0 taken 237 times.
✓ Branch 1 taken 668 times.
905 if (fc->tab.sz.ctu_count != ctu_count) {
380 237 ff_refstruct_pool_uninit(&fc->rpl_tab_pool);
381 237 fc->rpl_tab_pool = ff_refstruct_pool_alloc(ctu_count * sizeof(RefPicListTab), 0);
382
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 237 times.
237 if (!fc->rpl_tab_pool)
383 return AVERROR(ENOMEM);
384 }
385
386
2/2
✓ Branch 0 taken 237 times.
✓ Branch 1 taken 668 times.
905 if (fc->tab.sz.pic_size_in_min_pu != pic_size_in_min_pu) {
387 237 ff_refstruct_pool_uninit(&fc->tab_dmvr_mvf_pool);
388 237 fc->tab_dmvr_mvf_pool = ff_refstruct_pool_alloc(
389 pic_size_in_min_pu * sizeof(MvField), FF_REFSTRUCT_POOL_FLAG_ZERO_EVERY_TIME);
390
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 237 times.
237 if (!fc->tab_dmvr_mvf_pool)
391 return AVERROR(ENOMEM);
392 }
393
394 905 fc->tab.sz.ctu_count = pps->ctb_count;
395 905 fc->tab.sz.ctu_size = 1 << sps->ctb_log2_size_y << sps->ctb_log2_size_y;
396 905 fc->tab.sz.pic_size_in_min_cb = pps->min_cb_width * pps->min_cb_height;
397 905 fc->tab.sz.pic_size_in_min_pu = pic_size_in_min_pu;
398 905 fc->tab.sz.pic_size_in_min_tu = pps->min_tu_width * pps->min_tu_height;
399 905 fc->tab.sz.width = pps->width;
400 905 fc->tab.sz.height = pps->height;
401 905 fc->tab.sz.ctu_width = pps->ctb_width;
402 905 fc->tab.sz.ctu_height = pps->ctb_height;
403 905 fc->tab.sz.chroma_format_idc = sps->r->sps_chroma_format_idc;
404 905 fc->tab.sz.pixel_shift = sps->pixel_shift;
405
406 905 return 0;
407 }
408
409 905 int ff_vvc_per_frame_init(VVCFrameContext *fc)
410 {
411 905 return frame_context_for_each_tl(fc, tl_zero);
412 }
413
414 2886 static int min_positive(const int idx, const int diff, const int min_diff)
415 {
416
5/6
✓ Branch 0 taken 2508 times.
✓ Branch 1 taken 378 times.
✓ Branch 2 taken 945 times.
✓ Branch 3 taken 1563 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 945 times.
2886 return diff > 0 && (idx < 0 || diff < min_diff);
417 }
418
419 2886 static int max_negtive(const int idx, const int diff, const int max_diff)
420 {
421
5/6
✓ Branch 0 taken 1788 times.
✓ Branch 1 taken 1098 times.
✓ Branch 2 taken 665 times.
✓ Branch 3 taken 1123 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 665 times.
2886 return diff < 0 && (idx < 0 || diff > max_diff);
422 }
423
424 typedef int (*smvd_find_fxn)(const int idx, const int diff, const int old_diff);
425
426 3174 static int8_t smvd_find(const VVCFrameContext *fc, const SliceContext *sc, int lx, smvd_find_fxn find)
427 {
428 3174 const H266RawSliceHeader *rsh = sc->sh.r;
429 3174 const RefPicList *rpl = sc->rpl + lx;
430 3174 const int poc = fc->ref->poc;
431 3174 int8_t idx = -1;
432 3174 int old_diff = -1;
433
2/2
✓ Branch 0 taken 5772 times.
✓ Branch 1 taken 3174 times.
8946 for (int i = 0; i < rsh->num_ref_idx_active[lx]; i++) {
434
1/2
✓ Branch 0 taken 5772 times.
✗ Branch 1 not taken.
5772 if (!rpl->refs[i].is_lt) {
435 5772 int diff = poc - rpl->refs[i].poc;
436
2/2
✓ Branch 1 taken 2686 times.
✓ Branch 2 taken 3086 times.
5772 if (find(idx, diff, old_diff)) {
437 2686 idx = i;
438 2686 old_diff = diff;
439 }
440 }
441 }
442 3174 return idx;
443 }
444
445 1365 static void smvd_ref_idx(const VVCFrameContext *fc, SliceContext *sc)
446 {
447 1365 VVCSH *sh = &sc->sh;
448
2/2
✓ Branch 0 taken 1343 times.
✓ Branch 1 taken 22 times.
1365 if (IS_B(sh->r)) {
449 1343 sh->ref_idx_sym[0] = smvd_find(fc, sc, 0, min_positive);
450 1343 sh->ref_idx_sym[1] = smvd_find(fc, sc, 1, max_negtive);
451
4/4
✓ Branch 0 taken 1331 times.
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 232 times.
✓ Branch 3 taken 1099 times.
1343 if (sh->ref_idx_sym[0] == -1 || sh->ref_idx_sym[1] == -1) {
452 244 sh->ref_idx_sym[0] = smvd_find(fc, sc, 0, max_negtive);
453 244 sh->ref_idx_sym[1] = smvd_find(fc, sc, 1, min_positive);
454 }
455 }
456 1365 }
457
458 1403 static void eps_free(SliceContext *slice)
459 {
460 1403 av_freep(&slice->eps);
461 1403 slice->nb_eps = 0;
462 1403 }
463
464 640 static void slices_free(VVCFrameContext *fc)
465 {
466
2/2
✓ Branch 0 taken 237 times.
✓ Branch 1 taken 403 times.
640 if (fc->slices) {
467
2/2
✓ Branch 0 taken 751 times.
✓ Branch 1 taken 237 times.
988 for (int i = 0; i < fc->nb_slices_allocated; i++) {
468 751 SliceContext *slice = fc->slices[i];
469
1/2
✓ Branch 0 taken 751 times.
✗ Branch 1 not taken.
751 if (slice) {
470 751 ff_refstruct_unref(&slice->ref);
471 751 ff_refstruct_unref(&slice->sh.r);
472 751 eps_free(slice);
473 751 av_free(slice);
474 }
475 }
476 237 av_freep(&fc->slices);
477 }
478 640 fc->nb_slices_allocated = 0;
479 640 fc->nb_slices = 0;
480 640 }
481
482 1628 static int slices_realloc(VVCFrameContext *fc)
483 {
484 void *p;
485 1628 const int size = (fc->nb_slices_allocated + 1) * 3 / 2;
486
487
2/2
✓ Branch 0 taken 1290 times.
✓ Branch 1 taken 338 times.
1628 if (fc->nb_slices < fc->nb_slices_allocated)
488 1290 return 0;
489
490 338 p = av_realloc_array(fc->slices, size, sizeof(*fc->slices));
491
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 338 times.
338 if (!p)
492 return AVERROR(ENOMEM);
493
494 338 fc->slices = p;
495
2/2
✓ Branch 0 taken 751 times.
✓ Branch 1 taken 338 times.
1089 for (int i = fc->nb_slices_allocated; i < size; i++) {
496 751 fc->slices[i] = av_mallocz(sizeof(*fc->slices[0]));
497
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 751 times.
751 if (!fc->slices[i]) {
498 fc->nb_slices_allocated = i;
499 return AVERROR(ENOMEM);
500 }
501 751 fc->slices[i]->slice_idx = i;
502 }
503 338 fc->nb_slices_allocated = size;
504
505 338 return 0;
506 }
507
508 1995 static int ep_init_cabac_decoder(SliceContext *sc, const int index,
509 const H2645NAL *nal, GetBitContext *gb, const CodedBitstreamUnit *unit)
510 {
511 1995 const H266RawSlice *slice = unit->content_ref;
512 1995 const H266RawSliceHeader *rsh = sc->sh.r;
513 1995 EntryPoint *ep = sc->eps + index;
514 int size;
515 int ret;
516
517
2/2
✓ Branch 0 taken 367 times.
✓ Branch 1 taken 1628 times.
1995 if (index < rsh->num_entry_points) {
518 367 int skipped = 0;
519 367 int64_t start = (gb->index >> 3);
520 367 int64_t end = start + rsh->sh_entry_point_offset_minus1[index] + 1;
521
3/4
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 361 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
367 while (skipped < nal->skipped_bytes && nal->skipped_bytes_pos[skipped] <= start + slice->header_size) {
522 skipped++;
523 }
524
3/4
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 361 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
367 while (skipped < nal->skipped_bytes && nal->skipped_bytes_pos[skipped] <= end + slice->header_size) {
525 end--;
526 skipped++;
527 }
528 367 size = end - start;
529 367 size = av_clip(size, 0, get_bits_left(gb) / 8);
530 } else {
531 1628 size = get_bits_left(gb) / 8;
532 }
533
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1995 times.
1995 av_assert0(gb->buffer + get_bits_count(gb) / 8 + size <= gb->buffer_end);
534 1995 ret = ff_init_cabac_decoder (&ep->cc, gb->buffer + get_bits_count(gb) / 8, size);
535
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1995 times.
1995 if (ret < 0)
536 return ret;
537 1995 skip_bits(gb, size * 8);
538 1995 return 0;
539 }
540
541 1628 static int slice_init_entry_points(SliceContext *sc,
542 VVCFrameContext *fc, const H2645NAL *nal, const CodedBitstreamUnit *unit)
543 {
544 1628 const VVCSH *sh = &sc->sh;
545 1628 const H266RawSlice *slice = unit->content_ref;
546 1628 int nb_eps = sh->r->num_entry_points + 1;
547 1628 int ctu_addr = 0;
548 GetBitContext gb;
549 int ret;
550
551
2/2
✓ Branch 0 taken 652 times.
✓ Branch 1 taken 976 times.
1628 if (sc->nb_eps != nb_eps) {
552 652 eps_free(sc);
553 652 sc->eps = av_calloc(nb_eps, sizeof(*sc->eps));
554
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 652 times.
652 if (!sc->eps)
555 return AVERROR(ENOMEM);
556 652 sc->nb_eps = nb_eps;
557 }
558
559 1628 ret = init_get_bits8(&gb, slice->data, slice->data_size);
560
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1628 times.
1628 if (ret < 0)
561 return ret;
562
2/2
✓ Branch 0 taken 1995 times.
✓ Branch 1 taken 1628 times.
3623 for (int i = 0; i < sc->nb_eps; i++)
563 {
564 1995 EntryPoint *ep = sc->eps + i;
565
566 1995 ep->ctu_start = ctu_addr;
567
2/2
✓ Branch 0 taken 1628 times.
✓ Branch 1 taken 367 times.
1995 ep->ctu_end = (i + 1 == sc->nb_eps ? sh->num_ctus_in_curr_slice : sh->entry_point_start_ctu[i]);
568
569
2/2
✓ Branch 0 taken 44552 times.
✓ Branch 1 taken 1995 times.
46547 for (int j = ep->ctu_start; j < ep->ctu_end; j++) {
570 44552 const int rs = sc->sh.ctb_addr_in_curr_slice[j];
571 44552 fc->tab.slice_idx[rs] = sc->slice_idx;
572 }
573
574 1995 ret = ep_init_cabac_decoder(sc, i, nal, &gb, unit);
575
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1995 times.
1995 if (ret < 0)
576 return ret;
577
578
2/2
✓ Branch 0 taken 367 times.
✓ Branch 1 taken 1628 times.
1995 if (i + 1 < sc->nb_eps)
579 367 ctu_addr = sh->entry_point_start_ctu[i];
580 }
581
582 1628 return 0;
583 }
584
585 2817 static VVCFrameContext* get_frame_context(const VVCContext *s, const VVCFrameContext *fc, const int delta)
586 {
587 2817 const int size = s->nb_fcs;
588 2817 const int idx = (fc - s->fcs + delta + size) % size;
589 2817 return s->fcs + idx;
590 }
591
592 4226 static int ref_frame(VVCFrame *dst, const VVCFrame *src)
593 {
594 int ret;
595
596 4226 ret = av_frame_ref(dst->frame, src->frame);
597
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4226 times.
4226 if (ret < 0)
598 return ret;
599
600 4226 ff_refstruct_replace(&dst->sps, src->sps);
601 4226 ff_refstruct_replace(&dst->pps, src->pps);
602
603 4226 ff_refstruct_replace(&dst->progress, src->progress);
604
605 4226 ff_refstruct_replace(&dst->tab_dmvr_mvf, src->tab_dmvr_mvf);
606
607 4226 ff_refstruct_replace(&dst->rpl_tab, src->rpl_tab);
608 4226 ff_refstruct_replace(&dst->rpl, src->rpl);
609 4226 dst->nb_rpl_elems = src->nb_rpl_elems;
610
611 4226 dst->poc = src->poc;
612 4226 dst->ctb_count = src->ctb_count;
613
614 4226 dst->scaling_win = src->scaling_win;
615 4226 dst->ref_width = src->ref_width;
616 4226 dst->ref_height = src->ref_height;
617
618 4226 dst->flags = src->flags;
619 4226 dst->sequence = src->sequence;
620
621 4226 return 0;
622 }
623
624 640 static av_cold void frame_context_free(VVCFrameContext *fc)
625 {
626 640 slices_free(fc);
627
628 640 ff_refstruct_pool_uninit(&fc->tu_pool);
629 640 ff_refstruct_pool_uninit(&fc->cu_pool);
630
631
2/2
✓ Branch 0 taken 10880 times.
✓ Branch 1 taken 640 times.
11520 for (int i = 0; i < FF_ARRAY_ELEMS(fc->DPB); i++) {
632 10880 ff_vvc_unref_frame(fc, &fc->DPB[i], ~0);
633 10880 av_frame_free(&fc->DPB[i].frame);
634 }
635
636 640 ff_vvc_frame_thread_free(fc);
637 640 pic_arrays_free(fc);
638 640 av_frame_free(&fc->output_frame);
639 640 ff_vvc_frame_ps_free(&fc->ps);
640 640 }
641
642 640 static av_cold int frame_context_init(VVCFrameContext *fc, AVCodecContext *avctx)
643 {
644
645 640 fc->log_ctx = avctx;
646
647 640 fc->output_frame = av_frame_alloc();
648
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 640 times.
640 if (!fc->output_frame)
649 return AVERROR(ENOMEM);
650
651
2/2
✓ Branch 0 taken 10880 times.
✓ Branch 1 taken 640 times.
11520 for (int j = 0; j < FF_ARRAY_ELEMS(fc->DPB); j++) {
652 10880 fc->DPB[j].frame = av_frame_alloc();
653
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10880 times.
10880 if (!fc->DPB[j].frame)
654 return AVERROR(ENOMEM);
655 }
656 640 fc->cu_pool = ff_refstruct_pool_alloc(sizeof(CodingUnit), 0);
657
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 640 times.
640 if (!fc->cu_pool)
658 return AVERROR(ENOMEM);
659
660 640 fc->tu_pool = ff_refstruct_pool_alloc(sizeof(TransformUnit), 0);
661
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 640 times.
640 if (!fc->tu_pool)
662 return AVERROR(ENOMEM);
663
664 640 return 0;
665 }
666
667 905 static int frame_context_setup(VVCFrameContext *fc, VVCContext *s)
668 {
669 int ret;
670
671 905 fc->ref = NULL;
672
673 // copy refs from the last frame
674
3/4
✓ Branch 0 taken 825 times.
✓ Branch 1 taken 80 times.
✓ Branch 2 taken 825 times.
✗ Branch 3 not taken.
905 if (s->nb_frames && s->nb_fcs > 1) {
675 825 VVCFrameContext *prev = get_frame_context(s, fc, -1);
676
2/2
✓ Branch 0 taken 14025 times.
✓ Branch 1 taken 825 times.
14850 for (int i = 0; i < FF_ARRAY_ELEMS(fc->DPB); i++) {
677 14025 ff_vvc_unref_frame(fc, &fc->DPB[i], ~0);
678
2/2
✓ Branch 0 taken 4226 times.
✓ Branch 1 taken 9799 times.
14025 if (prev->DPB[i].frame->buf[0]) {
679 4226 ret = ref_frame(&fc->DPB[i], &prev->DPB[i]);
680
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4226 times.
4226 if (ret < 0)
681 return ret;
682 }
683 }
684 }
685
686
4/4
✓ Branch 0 taken 902 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 84 times.
✓ Branch 3 taken 818 times.
905 if (IS_IDR(s)) {
687 87 s->seq_decode = (s->seq_decode + 1) & 0xff;
688 87 ff_vvc_clear_refs(fc);
689 }
690
691 905 ret = pic_arrays_init(s, fc);
692
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 905 times.
905 if (ret < 0)
693 return ret;
694 905 ff_vvc_dsp_init(&fc->vvcdsp, fc->ps.sps->bit_depth);
695 905 ff_videodsp_init(&fc->vdsp, fc->ps.sps->bit_depth);
696 905 return 0;
697 }
698
699 905 static int frame_start(VVCContext *s, VVCFrameContext *fc, SliceContext *sc)
700 {
701 905 const VVCPH *ph = &fc->ps.ph;
702 905 const H266RawSliceHeader *rsh = sc->sh.r;
703 int ret;
704
705 // 8.3.1 Decoding process for picture order count
706
5/8
✓ Branch 0 taken 184 times.
✓ Branch 1 taken 721 times.
✓ Branch 2 taken 184 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 184 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 184 times.
✗ Branch 7 not taken.
905 if (!s->temporal_id && !ph->r->ph_non_ref_pic_flag && !(IS_RASL(s) || IS_RADL(s)))
707 184 s->poc_tid0 = ph->poc;
708
709
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 905 times.
905 if ((ret = ff_vvc_set_new_ref(s, fc, &fc->frame)) < 0)
710 goto fail;
711
712
4/4
✓ Branch 0 taken 902 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 818 times.
✓ Branch 3 taken 84 times.
905 if (!IS_IDR(s))
713 818 ff_vvc_bump_frame(s, fc);
714
715 905 av_frame_unref(fc->output_frame);
716
717
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 905 times.
905 if ((ret = ff_vvc_output_frame(s, fc, fc->output_frame,rsh->sh_no_output_of_prior_pics_flag, 0)) < 0)
718 goto fail;
719
720
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 905 times.
905 if ((ret = ff_vvc_frame_rpl(s, fc, sc)) < 0)
721 goto fail;
722
723
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 905 times.
905 if ((ret = ff_vvc_frame_thread_init(fc)) < 0)
724 goto fail;
725 905 return 0;
726 fail:
727 if (fc->ref)
728 ff_vvc_unref_frame(fc, fc->ref, ~0);
729 fc->ref = NULL;
730 return ret;
731 }
732
733 1628 static int slice_start(SliceContext *sc, VVCContext *s, VVCFrameContext *fc,
734 const CodedBitstreamUnit *unit, const int is_first_slice)
735 {
736 1628 VVCSH *sh = &sc->sh;
737 int ret;
738
739 1628 ret = ff_vvc_decode_sh(sh, &fc->ps, unit);
740
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1628 times.
1628 if (ret < 0)
741 return ret;
742
743 1628 ff_refstruct_replace(&sc->ref, unit->content_ref);
744
745
2/2
✓ Branch 0 taken 905 times.
✓ Branch 1 taken 723 times.
1628 if (is_first_slice) {
746 905 ret = frame_start(s, fc, sc);
747
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 905 times.
905 if (ret < 0)
748 return ret;
749
1/2
✓ Branch 0 taken 723 times.
✗ Branch 1 not taken.
723 } else if (fc->ref) {
750
2/2
✓ Branch 0 taken 561 times.
✓ Branch 1 taken 162 times.
723 if (!IS_I(sh->r)) {
751 561 ret = ff_vvc_slice_rpl(s, fc, sc);
752
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 561 times.
561 if (ret < 0) {
753 av_log(fc->log_ctx, AV_LOG_WARNING,
754 "Error constructing the reference lists for the current slice.\n");
755 return ret;
756 }
757 }
758 } else {
759 av_log(fc->log_ctx, AV_LOG_ERROR, "First slice in a frame missing.\n");
760 return ret;
761 }
762
763
2/2
✓ Branch 0 taken 1365 times.
✓ Branch 1 taken 263 times.
1628 if (!IS_I(sh->r))
764 1365 smvd_ref_idx(fc, sc);
765
766 1628 return 0;
767 }
768
769 905 static void export_frame_params(VVCContext *s, const VVCFrameContext *fc)
770 {
771 905 AVCodecContext *c = s->avctx;
772 905 const VVCSPS *sps = fc->ps.sps;
773 905 const VVCPPS *pps = fc->ps.pps;
774
775 905 c->pix_fmt = sps->pix_fmt;
776 905 c->coded_width = pps->width;
777 905 c->coded_height = pps->height;
778 905 c->width = pps->width - ((pps->r->pps_conf_win_left_offset + pps->r->pps_conf_win_right_offset) << sps->hshift[CHROMA]);
779 905 c->height = pps->height - ((pps->r->pps_conf_win_top_offset + pps->r->pps_conf_win_bottom_offset) << sps->vshift[CHROMA]);
780 905 c->has_b_frames = sps->r->sps_dpb_params.dpb_max_num_reorder_pics[sps->r->sps_max_sublayers_minus1];
781 905 }
782
783 905 static int frame_setup(VVCFrameContext *fc, VVCContext *s)
784 {
785 905 int ret = ff_vvc_decode_frame_ps(&fc->ps, s);
786
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 905 times.
905 if (ret < 0)
787 return ret;
788
789 905 ret = frame_context_setup(fc, s);
790
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 905 times.
905 if (ret < 0)
791 return ret;
792
793 905 export_frame_params(s, fc);
794 905 return ret;
795 }
796
797 1628 static int decode_slice(VVCContext *s, VVCFrameContext *fc, const H2645NAL *nal, const CodedBitstreamUnit *unit)
798 {
799 int ret;
800 SliceContext *sc;
801 1628 const int is_first_slice = !fc->nb_slices;
802
803 1628 ret = slices_realloc(fc);
804
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1628 times.
1628 if (ret < 0)
805 return ret;
806
807 1628 sc = fc->slices[fc->nb_slices];
808
809 1628 s->vcl_unit_type = nal->type;
810
2/2
✓ Branch 0 taken 905 times.
✓ Branch 1 taken 723 times.
1628 if (is_first_slice) {
811 905 ret = frame_setup(fc, s);
812
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 905 times.
905 if (ret < 0)
813 return ret;
814 }
815
816 1628 ret = slice_start(sc, s, fc, unit, is_first_slice);
817
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1628 times.
1628 if (ret < 0)
818 return ret;
819
820 1628 ret = slice_init_entry_points(sc, fc, nal, unit);
821
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1628 times.
1628 if (ret < 0)
822 return ret;
823 1628 fc->nb_slices++;
824
825 1628 return 0;
826 }
827
828 3269 static int decode_nal_unit(VVCContext *s, VVCFrameContext *fc, const H2645NAL *nal, const CodedBitstreamUnit *unit)
829 {
830 int ret;
831
832 3269 s->temporal_id = nal->temporal_id;
833
834
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3269 times.
3269 if (nal->nuh_layer_id > 0) {
835 avpriv_report_missing_feature(fc->log_ctx,
836 "Decoding of multilayer bitstreams");
837 return AVERROR_PATCHWELCOME;
838 }
839
840
4/4
✓ Branch 0 taken 275 times.
✓ Branch 1 taken 1628 times.
✓ Branch 2 taken 315 times.
✓ Branch 3 taken 1051 times.
3269 switch (unit->type) {
841 275 case VVC_VPS_NUT:
842 case VVC_SPS_NUT:
843 case VVC_PPS_NUT:
844 /* vps, sps, sps cached by s->cbc */
845 275 break;
846 1628 case VVC_TRAIL_NUT:
847 case VVC_STSA_NUT:
848 case VVC_RADL_NUT:
849 case VVC_RASL_NUT:
850 case VVC_IDR_W_RADL:
851 case VVC_IDR_N_LP:
852 case VVC_CRA_NUT:
853 case VVC_GDR_NUT:
854 1628 ret = decode_slice(s, fc, nal, unit);
855
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1628 times.
1628 if (ret < 0)
856 return ret;
857 1628 break;
858 315 case VVC_PREFIX_APS_NUT:
859 case VVC_SUFFIX_APS_NUT:
860 315 ret = ff_vvc_decode_aps(&s->ps, unit);
861
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 315 times.
315 if (ret < 0)
862 return ret;
863 315 break;
864 }
865
866 3269 return 0;
867 }
868
869 905 static int decode_nal_units(VVCContext *s, VVCFrameContext *fc, AVPacket *avpkt)
870 {
871 905 const CodedBitstreamH266Context *h266 = s->cbc->priv_data;
872 905 CodedBitstreamFragment *frame = &s->current_frame;
873 905 int ret = 0;
874 905 s->last_eos = s->eos;
875 905 s->eos = 0;
876
877 905 ff_cbs_fragment_reset(frame);
878 905 ret = ff_cbs_read_packet(s->cbc, frame, avpkt);
879
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 905 times.
905 if (ret < 0) {
880 av_log(s->avctx, AV_LOG_ERROR, "Failed to read packet.\n");
881 return ret;
882 }
883 /* decode the NAL units */
884
2/2
✓ Branch 0 taken 3269 times.
✓ Branch 1 taken 905 times.
4174 for (int i = 0; i < frame->nb_units; i++) {
885 3269 const H2645NAL *nal = h266->common.read_packet.nals + i;
886 3269 const CodedBitstreamUnit *unit = frame->units + i;
887
888
2/4
✓ Branch 0 taken 3269 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 3269 times.
3269 if (unit->type == VVC_EOB_NUT || unit->type == VVC_EOS_NUT) {
889 s->last_eos = 1;
890 } else {
891 3269 ret = decode_nal_unit(s, fc, nal, unit);
892
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3269 times.
3269 if (ret < 0) {
893 av_log(s->avctx, AV_LOG_WARNING,
894 "Error parsing NAL unit #%d.\n", i);
895 goto fail;
896 }
897 }
898 }
899 905 return 0;
900
901 fail:
902 if (fc->ref)
903 ff_vvc_report_frame_finished(fc->ref);
904 return ret;
905 }
906
907 836 static int set_output_format(const VVCContext *s, const AVFrame *output)
908 {
909 836 AVCodecContext *c = s->avctx;
910 int ret;
911
912
3/4
✓ Branch 0 taken 745 times.
✓ Branch 1 taken 91 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 745 times.
836 if (output->width != c->width || output->height != c->height) {
913
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 91 times.
91 if ((ret = ff_set_dimensions(c, output->width, output->height)) < 0)
914 return ret;
915 }
916 836 c->pix_fmt = output->format;
917 836 return 0;
918 }
919
920 905 static int wait_delayed_frame(VVCContext *s, AVFrame *output, int *got_output)
921 {
922 905 VVCFrameContext *delayed = get_frame_context(s, s->fcs, s->nb_frames - s->nb_delayed);
923 905 int ret = ff_vvc_frame_wait(s, delayed);
924
925
5/6
✓ Branch 0 taken 905 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 775 times.
✓ Branch 3 taken 130 times.
✓ Branch 4 taken 760 times.
✓ Branch 5 taken 15 times.
905 if (!ret && delayed->output_frame->buf[0] && output) {
926 760 av_frame_move_ref(output, delayed->output_frame);
927 760 ret = set_output_format(s, output);
928
1/2
✓ Branch 0 taken 760 times.
✗ Branch 1 not taken.
760 if (!ret)
929 760 *got_output = 1;
930 }
931 905 s->nb_delayed--;
932
933 905 return ret;
934 }
935
936 905 static int submit_frame(VVCContext *s, VVCFrameContext *fc, AVFrame *output, int *got_output)
937 {
938 905 int ret = ff_vvc_frame_submit(s, fc);
939
940
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 905 times.
905 if (ret < 0) {
941 ff_vvc_report_frame_finished(fc->ref);
942 return ret;
943 }
944
945 905 s->nb_frames++;
946 905 s->nb_delayed++;
947
948
2/2
✓ Branch 0 taken 688 times.
✓ Branch 1 taken 217 times.
905 if (s->nb_delayed >= s->nb_fcs) {
949
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 688 times.
688 if ((ret = wait_delayed_frame(s, output, got_output)) < 0)
950 return ret;
951 }
952 905 return 0;
953 }
954
955 247 static int get_decoded_frame(VVCContext *s, AVFrame *output, int *got_output)
956 {
957 int ret;
958
2/2
✓ Branch 0 taken 163 times.
✓ Branch 1 taken 102 times.
265 while (s->nb_delayed) {
959
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 163 times.
163 if ((ret = wait_delayed_frame(s, output, got_output)) < 0)
960 return ret;
961
2/2
✓ Branch 0 taken 145 times.
✓ Branch 1 taken 18 times.
163 if (*got_output)
962 145 return 0;
963 }
964
1/2
✓ Branch 0 taken 102 times.
✗ Branch 1 not taken.
102 if (s->nb_frames) {
965 //we still have frames cached in dpb.
966 102 VVCFrameContext *last = get_frame_context(s, s->fcs, s->nb_frames - 1);
967
968 102 ret = ff_vvc_output_frame(s, last, output, 0, 1);
969
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 102 times.
102 if (ret < 0)
970 return ret;
971
2/2
✓ Branch 0 taken 76 times.
✓ Branch 1 taken 26 times.
102 if (ret) {
972 76 *got_output = ret;
973
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 76 times.
76 if ((ret = set_output_format(s, output)) < 0)
974 return ret;
975 }
976 }
977 102 return 0;
978 }
979
980 1152 static int vvc_decode_frame(AVCodecContext *avctx, AVFrame *output,
981 int *got_output, AVPacket *avpkt)
982 {
983 1152 VVCContext *s = avctx->priv_data;
984 VVCFrameContext *fc;
985 int ret;
986
987
2/2
✓ Branch 0 taken 247 times.
✓ Branch 1 taken 905 times.
1152 if (!avpkt->size)
988 247 return get_decoded_frame(s, output, got_output);
989
990 905 fc = get_frame_context(s, s->fcs, s->nb_frames);
991
992 905 fc->nb_slices = 0;
993 905 fc->decode_order = s->nb_frames;
994
995 905 ret = decode_nal_units(s, fc, avpkt);
996
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 905 times.
905 if (ret < 0)
997 return ret;
998
999
2/4
✓ Branch 0 taken 905 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 905 times.
905 if (!fc->ft || !fc->ref)
1000 return avpkt->size;
1001
1002 905 ret = submit_frame(s, fc, output, got_output);
1003
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 905 times.
905 if (ret < 0)
1004 return ret;
1005
1006 905 return avpkt->size;
1007 }
1008
1009 80 static av_cold void vvc_decode_flush(AVCodecContext *avctx)
1010 {
1011 80 VVCContext *s = avctx->priv_data;
1012 80 int got_output = 0;
1013
1014
2/2
✓ Branch 0 taken 54 times.
✓ Branch 1 taken 80 times.
134 while (s->nb_delayed)
1015 54 wait_delayed_frame(s, NULL, &got_output);
1016
1017
1/2
✓ Branch 0 taken 80 times.
✗ Branch 1 not taken.
80 if (s->fcs) {
1018 80 VVCFrameContext *last = get_frame_context(s, s->fcs, s->nb_frames - 1);
1019 80 ff_vvc_flush_dpb(last);
1020 }
1021
1022 80 s->ps.sps_id_used = 0;
1023
1024 80 s->eos = 1;
1025 80 }
1026
1027 80 static av_cold int vvc_decode_free(AVCodecContext *avctx)
1028 {
1029 80 VVCContext *s = avctx->priv_data;
1030
1031 80 ff_cbs_fragment_free(&s->current_frame);
1032 80 vvc_decode_flush(avctx);
1033 80 ff_vvc_executor_free(&s->executor);
1034
1/2
✓ Branch 0 taken 80 times.
✗ Branch 1 not taken.
80 if (s->fcs) {
1035
2/2
✓ Branch 0 taken 640 times.
✓ Branch 1 taken 80 times.
720 for (int i = 0; i < s->nb_fcs; i++)
1036 640 frame_context_free(s->fcs + i);
1037 80 av_free(s->fcs);
1038 }
1039 80 ff_vvc_ps_uninit(&s->ps);
1040 80 ff_cbs_close(&s->cbc);
1041
1042 80 return 0;
1043 }
1044
1045 54 static av_cold void init_default_scale_m(void)
1046 {
1047 54 memset(&ff_vvc_default_scale_m, 16, sizeof(ff_vvc_default_scale_m));
1048 54 }
1049
1050 #define VVC_MAX_DELAYED_FRAMES 16
1051 80 static av_cold int vvc_decode_init(AVCodecContext *avctx)
1052 {
1053 80 VVCContext *s = avctx->priv_data;
1054 static AVOnce init_static_once = AV_ONCE_INIT;
1055 80 const int cpu_count = av_cpu_count();
1056 80 const int delayed = FFMIN(cpu_count, VVC_MAX_DELAYED_FRAMES);
1057
1/2
✓ Branch 0 taken 80 times.
✗ Branch 1 not taken.
80 int thread_count = avctx->thread_count ? avctx->thread_count : delayed;
1058 int ret;
1059
1060 80 s->avctx = avctx;
1061
1062 80 ret = ff_cbs_init(&s->cbc, AV_CODEC_ID_VVC, avctx);
1063
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 80 times.
80 if (ret)
1064 return ret;
1065
1066
3/4
✓ Branch 0 taken 27 times.
✓ Branch 1 taken 53 times.
✓ Branch 2 taken 27 times.
✗ Branch 3 not taken.
80 if (avctx->extradata_size > 0 && avctx->extradata) {
1067 27 ret = ff_cbs_read_extradata_from_codec(s->cbc, &s->current_frame, avctx);
1068
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 27 times.
27 if (ret < 0)
1069 return ret;
1070 }
1071
1072
1/2
✓ Branch 0 taken 80 times.
✗ Branch 1 not taken.
80 s->nb_fcs = (avctx->flags & AV_CODEC_FLAG_LOW_DELAY) ? 1 : delayed;
1073 80 s->fcs = av_calloc(s->nb_fcs, sizeof(*s->fcs));
1074
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 80 times.
80 if (!s->fcs)
1075 return AVERROR(ENOMEM);
1076
1077
2/2
✓ Branch 0 taken 640 times.
✓ Branch 1 taken 80 times.
720 for (int i = 0; i < s->nb_fcs; i++) {
1078 640 VVCFrameContext *fc = s->fcs + i;
1079 640 ret = frame_context_init(fc, avctx);
1080
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 640 times.
640 if (ret < 0)
1081 return ret;
1082 }
1083
1084
1/2
✓ Branch 0 taken 80 times.
✗ Branch 1 not taken.
80 if (thread_count == 1)
1085 80 thread_count = 0;
1086 80 s->executor = ff_vvc_executor_alloc(s, thread_count);
1087
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 80 times.
80 if (!s->executor)
1088 return AVERROR(ENOMEM);
1089
1090 80 s->eos = 1;
1091 80 GDR_SET_RECOVERED(s);
1092 80 ff_thread_once(&init_static_once, init_default_scale_m);
1093
1094 80 return 0;
1095 }
1096
1097 const FFCodec ff_vvc_decoder = {
1098 .p.name = "vvc",
1099 .p.long_name = NULL_IF_CONFIG_SMALL("VVC (Versatile Video Coding)"),
1100 .p.type = AVMEDIA_TYPE_VIDEO,
1101 .p.id = AV_CODEC_ID_VVC,
1102 .priv_data_size = sizeof(VVCContext),
1103 .init = vvc_decode_init,
1104 .close = vvc_decode_free,
1105 FF_CODEC_DECODE_CB(vvc_decode_frame),
1106 .flush = vvc_decode_flush,
1107 .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY | AV_CODEC_CAP_OTHER_THREADS,
1108 .caps_internal = FF_CODEC_CAP_EXPORTS_CROPPING | FF_CODEC_CAP_INIT_CLEANUP |
1109 FF_CODEC_CAP_AUTO_THREADS,
1110 .p.profiles = NULL_IF_CONFIG_SMALL(ff_vvc_profiles),
1111 };
1112