FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/vvc/dec.c
Date: 2025-06-23 20:06:14
Exec Total Coverage
Lines: 650 769 84.5%
Functions: 56 56 100.0%
Branches: 388 563 68.9%

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/hwaccel_internal.h"
26 #include "libavcodec/hwconfig.h"
27 #include "libavcodec/profiles.h"
28 #include "libavutil/refstruct.h"
29 #include "libavcodec/aom_film_grain.h"
30 #include "libavcodec/thread.h"
31 #include "libavutil/cpu.h"
32 #include "libavutil/mem.h"
33 #include "libavutil/thread.h"
34 #include "libavutil/film_grain_params.h"
35
36 #include "dec.h"
37 #include "ctu.h"
38 #include "data.h"
39 #include "refs.h"
40 #include "thread.h"
41 #include "config_components.h"
42
43 #define TAB_MAX 32
44
45 typedef struct Tab {
46 void **tab;
47 size_t size;
48 } Tab;
49
50 typedef struct TabList {
51 Tab tabs[TAB_MAX];
52 int nb_tabs;
53
54 int zero;
55 int realloc;
56 } TabList;
57
58 #define TL_ADD(t, s) do { \
59 av_assert0(l->nb_tabs < TAB_MAX); \
60 l->tabs[l->nb_tabs].tab = (void**)&fc->tab.t; \
61 l->tabs[l->nb_tabs].size = sizeof(*fc->tab.t) * (s); \
62 l->nb_tabs++; \
63 } while (0)
64
65 28721 static void tl_init(TabList *l, const int zero, const int realloc)
66 {
67 28721 l->nb_tabs = 0;
68 28721 l->zero = zero;
69 28721 l->realloc = realloc;
70 28721 }
71
72 11235 static int tl_free(TabList *l)
73 {
74
2/2
✓ Branch 0 taken 68247 times.
✓ Branch 1 taken 11235 times.
79482 for (int i = 0; i < l->nb_tabs; i++)
75 68247 av_freep(l->tabs[i].tab);
76
77 11235 return 0;
78 }
79
80 10571 static int tl_create(TabList *l)
81 {
82
2/2
✓ Branch 0 taken 3491 times.
✓ Branch 1 taken 7080 times.
10571 if (l->realloc) {
83 3491 tl_free(l);
84
85
2/2
✓ Branch 0 taken 20979 times.
✓ Branch 1 taken 3491 times.
24470 for (int i = 0; i < l->nb_tabs; i++) {
86 20979 Tab *t = l->tabs + i;
87
2/2
✓ Branch 0 taken 4418 times.
✓ Branch 1 taken 16561 times.
20979 *t->tab = l->zero ? av_mallocz(t->size) : av_malloc(t->size);
88
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 20979 times.
20979 if (!*t->tab)
89 return AVERROR(ENOMEM);
90 }
91 }
92 10571 return 0;
93 }
94
95 10406 static int tl_zero(TabList *l)
96 {
97
2/2
✓ Branch 0 taken 4769 times.
✓ Branch 1 taken 5637 times.
10406 if (l->zero) {
98
2/2
✓ Branch 0 taken 16199 times.
✓ Branch 1 taken 4769 times.
20968 for (int i = 0; i < l->nb_tabs; i++) {
99 16199 Tab *t = l->tabs + i;
100 16199 memset(*t->tab, 0, t->size);
101 }
102 }
103 10406 return 0;
104 }
105
106 2611 static void ctu_nz_tl_init(TabList *l, VVCFrameContext *fc)
107 {
108 2611 const VVCSPS *sps = fc->ps.sps;
109 2611 const VVCPPS *pps = fc->ps.pps;
110
2/2
✓ Branch 0 taken 2160 times.
✓ Branch 1 taken 451 times.
2611 const int ctu_size = sps ? (1 << sps->ctb_log2_size_y << sps->ctb_log2_size_y) : 0;
111
2/2
✓ Branch 0 taken 2160 times.
✓ Branch 1 taken 451 times.
2611 const int ctu_count = pps ? pps->ctb_count : 0;
112
3/4
✓ Branch 0 taken 2358 times.
✓ Branch 1 taken 253 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2358 times.
2611 const int changed = fc->tab.sz.ctu_count != ctu_count || fc->tab.sz.ctu_size != ctu_size;
113
114 2611 tl_init(l, 0, changed);
115
116
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2611 times.
2611 TL_ADD(cus, ctu_count);
117
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2611 times.
2611 TL_ADD(ctus, ctu_count);
118
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2611 times.
2611 TL_ADD(deblock, ctu_count);
119
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2611 times.
2611 TL_ADD(sao, ctu_count);
120
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2611 times.
2611 TL_ADD(alf, ctu_count);
121
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2611 times.
2611 TL_ADD(slice_idx, ctu_count);
122
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2611 times.
2611 TL_ADD(coeffs, ctu_count * ctu_size * VVC_MAX_SAMPLE_ARRAYS);
123 2611 }
124
125 2611 static void min_cb_tl_init(TabList *l, VVCFrameContext *fc)
126 {
127 2611 const VVCPPS *pps = fc->ps.pps;
128
2/2
✓ Branch 0 taken 2160 times.
✓ Branch 1 taken 451 times.
2611 const int pic_size_in_min_cb = pps ? pps->min_cb_width * pps->min_cb_height : 0;
129 2611 const int changed = fc->tab.sz.pic_size_in_min_cb != pic_size_in_min_cb;
130
131 2611 tl_init(l, 1, changed);
132
133
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2611 times.
2611 TL_ADD(imf, pic_size_in_min_cb);
134
135
2/2
✓ Branch 0 taken 5222 times.
✓ Branch 1 taken 2611 times.
7833 for (int i = LUMA; i <= CHROMA; i++)
136
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5222 times.
5222 TL_ADD(cb_width[i], pic_size_in_min_cb); //is_a0_available requires this
137 2611 }
138
139 2611 static void min_cb_nz_tl_init(TabList *l, VVCFrameContext *fc)
140 {
141 2611 const VVCPPS *pps = fc->ps.pps;
142
2/2
✓ Branch 0 taken 2160 times.
✓ Branch 1 taken 451 times.
2611 const int pic_size_in_min_cb = pps ? pps->min_cb_width * pps->min_cb_height : 0;
143 2611 const int changed = fc->tab.sz.pic_size_in_min_cb != pic_size_in_min_cb;
144
145 2611 tl_init(l, 0, changed);
146
147
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2611 times.
2611 TL_ADD(skip, pic_size_in_min_cb);
148
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2611 times.
2611 TL_ADD(ipm, pic_size_in_min_cb);
149
150
2/2
✓ Branch 0 taken 5222 times.
✓ Branch 1 taken 2611 times.
7833 for (int i = LUMA; i <= CHROMA; i++) {
151
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5222 times.
5222 TL_ADD(cqt_depth[i], pic_size_in_min_cb);
152
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5222 times.
5222 TL_ADD(cb_pos_x[i], pic_size_in_min_cb);
153
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5222 times.
5222 TL_ADD(cb_pos_y[i], pic_size_in_min_cb);
154
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5222 times.
5222 TL_ADD(cb_height[i], pic_size_in_min_cb);
155
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5222 times.
5222 TL_ADD(cp_mv[i], pic_size_in_min_cb * MAX_CONTROL_POINTS);
156
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5222 times.
5222 TL_ADD(cpm[i], pic_size_in_min_cb);
157
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5222 times.
5222 TL_ADD(pcmf[i], pic_size_in_min_cb);
158 }
159 // For luma, qp can only change at the CU level, so the qp tab size is related to the CU.
160
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2611 times.
2611 TL_ADD(qp[LUMA], pic_size_in_min_cb);
161 2611 }
162
163 2611 static void min_pu_tl_init(TabList *l, VVCFrameContext *fc)
164 {
165 2611 const VVCPPS *pps = fc->ps.pps;
166
2/2
✓ Branch 0 taken 2160 times.
✓ Branch 1 taken 451 times.
2611 const int pic_size_in_min_pu = pps ? pps->min_pu_width * pps->min_pu_height : 0;
167 2611 const int changed = fc->tab.sz.pic_size_in_min_pu != pic_size_in_min_pu;
168
169 2611 tl_init(l, 1, changed);
170
171
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2611 times.
2611 TL_ADD(iaf, pic_size_in_min_pu);
172 2611 }
173
174 2611 static void min_pu_nz_tl_init(TabList *l, VVCFrameContext *fc)
175 {
176 2611 const VVCPPS *pps = fc->ps.pps;
177
2/2
✓ Branch 0 taken 2160 times.
✓ Branch 1 taken 451 times.
2611 const int pic_size_in_min_pu = pps ? pps->min_pu_width * pps->min_pu_height : 0;
178 2611 const int changed = fc->tab.sz.pic_size_in_min_pu != pic_size_in_min_pu;
179
180 2611 tl_init(l, 0, changed);
181
182
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2611 times.
2611 TL_ADD(msf, pic_size_in_min_pu);
183
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2611 times.
2611 TL_ADD(mmi, pic_size_in_min_pu);
184
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2611 times.
2611 TL_ADD(mvf, pic_size_in_min_pu);
185 2611 }
186
187 2611 static void min_tu_tl_init(TabList *l, VVCFrameContext *fc)
188 {
189 2611 const VVCPPS *pps = fc->ps.pps;
190
2/2
✓ Branch 0 taken 2160 times.
✓ Branch 1 taken 451 times.
2611 const int pic_size_in_min_tu = pps ? pps->min_tu_width * pps->min_tu_height : 0;
191 2611 const int changed = fc->tab.sz.pic_size_in_min_tu != pic_size_in_min_tu;
192
193 2611 tl_init(l, 1, changed);
194
195
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2611 times.
2611 TL_ADD(tu_joint_cbcr_residual_flag, pic_size_in_min_tu);
196
197
2/2
✓ Branch 0 taken 7833 times.
✓ Branch 1 taken 2611 times.
10444 for (int i = 0; i < VVC_MAX_SAMPLE_ARRAYS; i++) {
198
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7833 times.
7833 TL_ADD(tu_coded_flag[i], pic_size_in_min_tu);
199
200
2/2
✓ Branch 0 taken 15666 times.
✓ Branch 1 taken 7833 times.
23499 for (int vertical = 0; vertical < 2; vertical++)
201
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15666 times.
15666 TL_ADD(bs[vertical][i], pic_size_in_min_tu);
202 }
203 2611 }
204
205 2611 static void min_tu_nz_tl_init(TabList *l, VVCFrameContext *fc)
206 {
207 2611 const VVCPPS *pps = fc->ps.pps;
208
2/2
✓ Branch 0 taken 2160 times.
✓ Branch 1 taken 451 times.
2611 const int pic_size_in_min_tu = pps ? pps->min_tu_width * pps->min_tu_height : 0;
209 2611 const int changed = fc->tab.sz.pic_size_in_min_tu != pic_size_in_min_tu;
210
211 2611 tl_init(l, 0, changed);
212
213
2/2
✓ Branch 0 taken 5222 times.
✓ Branch 1 taken 2611 times.
7833 for (int i = LUMA; i <= CHROMA; i++) {
214
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5222 times.
5222 TL_ADD(tb_width[i], pic_size_in_min_tu);
215
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5222 times.
5222 TL_ADD(tb_height[i], pic_size_in_min_tu);
216 }
217
218
2/2
✓ Branch 0 taken 5222 times.
✓ Branch 1 taken 2611 times.
7833 for (int vertical = 0; vertical < 2; vertical++) {
219
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5222 times.
5222 TL_ADD(max_len_p[vertical], pic_size_in_min_tu);
220
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5222 times.
5222 TL_ADD(max_len_q[vertical], pic_size_in_min_tu);
221 }
222
223 // For chroma, considering the joint CbCr, the QP tab size is related to the TU.
224
2/2
✓ Branch 0 taken 5222 times.
✓ Branch 1 taken 2611 times.
7833 for (int i = CB; i < VVC_MAX_SAMPLE_ARRAYS; i++)
225
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5222 times.
5222 TL_ADD(qp[i], pic_size_in_min_tu);
226 2611 }
227
228 2611 static void pixel_buffer_nz_tl_init(TabList *l, VVCFrameContext *fc)
229 {
230 2611 const VVCSPS *sps = fc->ps.sps;
231 2611 const VVCPPS *pps = fc->ps.pps;
232
2/2
✓ Branch 0 taken 2160 times.
✓ Branch 1 taken 451 times.
2611 const int width = pps ? pps->width : 0;
233
2/2
✓ Branch 0 taken 2160 times.
✓ Branch 1 taken 451 times.
2611 const int height = pps ? pps->height : 0;
234
2/2
✓ Branch 0 taken 2160 times.
✓ Branch 1 taken 451 times.
2611 const int ctu_width = pps ? pps->ctb_width : 0;
235
2/2
✓ Branch 0 taken 2160 times.
✓ Branch 1 taken 451 times.
2611 const int ctu_height = pps ? pps->ctb_height : 0;
236
2/2
✓ Branch 0 taken 2160 times.
✓ Branch 1 taken 451 times.
2611 const int chroma_idc = sps ? sps->r->sps_chroma_format_idc : 0;
237
2/2
✓ Branch 0 taken 2160 times.
✓ Branch 1 taken 451 times.
2611 const int ps = sps ? sps->pixel_shift : 0;
238
2/2
✓ Branch 0 taken 2018 times.
✓ Branch 1 taken 593 times.
2611 const int c_end = chroma_idc ? VVC_MAX_SAMPLE_ARRAYS : 1;
239 7590 const int changed = fc->tab.sz.chroma_format_idc != chroma_idc ||
240
3/4
✓ Branch 0 taken 2358 times.
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 2358 times.
✗ Branch 3 not taken.
2368 fc->tab.sz.width != width || fc->tab.sz.height != height ||
241
4/6
✓ Branch 0 taken 2368 times.
✓ Branch 1 taken 243 times.
✓ Branch 2 taken 2358 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2358 times.
✗ Branch 5 not taken.
7337 fc->tab.sz.ctu_width != ctu_width || fc->tab.sz.ctu_height != ctu_height ||
242
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2358 times.
2358 fc->tab.sz.pixel_shift != ps;
243
244 2611 tl_init(l, 0, changed);
245
246
2/2
✓ Branch 0 taken 6647 times.
✓ Branch 1 taken 2611 times.
9258 for (int c_idx = 0; c_idx < c_end; c_idx++) {
247
2/2
✓ Branch 0 taken 6196 times.
✓ Branch 1 taken 451 times.
6647 const int w = width >> (sps ? sps->hshift[c_idx] : 0);
248
2/2
✓ Branch 0 taken 6196 times.
✓ Branch 1 taken 451 times.
6647 const int h = height >> (sps ? sps->vshift[c_idx] : 0);
249
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6647 times.
6647 TL_ADD(sao_pixel_buffer_h[c_idx], (w * 2 * ctu_height) << ps);
250
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6647 times.
6647 TL_ADD(sao_pixel_buffer_v[c_idx], (h * 2 * ctu_width) << ps);
251 }
252
253
2/2
✓ Branch 0 taken 6647 times.
✓ Branch 1 taken 2611 times.
9258 for (int c_idx = 0; c_idx < c_end; c_idx++) {
254
2/2
✓ Branch 0 taken 6196 times.
✓ Branch 1 taken 451 times.
6647 const int w = width >> (sps ? sps->hshift[c_idx] : 0);
255
2/2
✓ Branch 0 taken 6196 times.
✓ Branch 1 taken 451 times.
6647 const int h = height >> (sps ? sps->vshift[c_idx] : 0);
256
2/2
✓ Branch 0 taken 4036 times.
✓ Branch 1 taken 2611 times.
6647 const int border_pixels = c_idx ? ALF_BORDER_CHROMA : ALF_BORDER_LUMA;
257
2/2
✓ Branch 0 taken 13294 times.
✓ Branch 1 taken 6647 times.
19941 for (int i = 0; i < 2; i++) {
258
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13294 times.
13294 TL_ADD(alf_pixel_buffer_h[c_idx][i], (w * border_pixels * ctu_height) << ps);
259
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13294 times.
13294 TL_ADD(alf_pixel_buffer_v[c_idx][i], h * ALF_PADDING_SIZE * ctu_width);
260 }
261 }
262 2611 }
263
264 2611 static void msm_tl_init(TabList *l, VVCFrameContext *fc)
265 {
266 2611 const VVCPPS *pps = fc->ps.pps;
267
2/2
✓ Branch 0 taken 2160 times.
✓ Branch 1 taken 451 times.
2611 const int w32 = pps ? AV_CEIL_RSHIFT(pps->width, 5) : 0;
268
2/2
✓ Branch 0 taken 2160 times.
✓ Branch 1 taken 451 times.
2611 const int h32 = pps ? AV_CEIL_RSHIFT(pps->height, 5) : 0;
269
2/2
✓ Branch 0 taken 2358 times.
✓ Branch 1 taken 253 times.
4969 const int changed = AV_CEIL_RSHIFT(fc->tab.sz.width, 5) != w32 ||
270
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2358 times.
2358 AV_CEIL_RSHIFT(fc->tab.sz.height, 5) != h32;
271
272 2611 tl_init(l, 1, changed);
273
274
2/2
✓ Branch 0 taken 5222 times.
✓ Branch 1 taken 2611 times.
7833 for (int i = LUMA; i <= CHROMA; i++)
275
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5222 times.
5222 TL_ADD(msm[i], w32 * h32);
276 2611 }
277
278 2611 static void ispmf_tl_init(TabList *l, VVCFrameContext *fc)
279 {
280 2611 const VVCPPS *pps = fc->ps.pps;
281
2/2
✓ Branch 0 taken 2160 times.
✓ Branch 1 taken 451 times.
2611 const int w64 = pps ? AV_CEIL_RSHIFT(pps->width, 6) : 0;
282
2/2
✓ Branch 0 taken 2160 times.
✓ Branch 1 taken 451 times.
2611 const int h64 = pps ? AV_CEIL_RSHIFT(pps->height, 6) : 0;
283
2/2
✓ Branch 0 taken 2358 times.
✓ Branch 1 taken 253 times.
4969 const int changed = AV_CEIL_RSHIFT(fc->tab.sz.width, 6) != w64 ||
284
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2358 times.
2358 AV_CEIL_RSHIFT(fc->tab.sz.height, 6) != h64;
285
286 2611 tl_init(l, 1, changed);
287
288
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2611 times.
2611 TL_ADD(ispmf, w64 * h64);
289 2611 }
290
291 2611 static void ibc_tl_init(TabList *l, VVCFrameContext *fc)
292 {
293 2611 const VVCSPS *sps = fc->ps.sps;
294 2611 const VVCPPS *pps = fc->ps.pps;
295
2/2
✓ Branch 0 taken 2160 times.
✓ Branch 1 taken 451 times.
2611 const int ctu_height = pps ? pps->ctb_height : 0;
296
2/2
✓ Branch 0 taken 2160 times.
✓ Branch 1 taken 451 times.
2611 const int ctu_size = sps ? sps->ctb_size_y : 0;
297
2/2
✓ Branch 0 taken 2160 times.
✓ Branch 1 taken 451 times.
2611 const int ps = sps ? sps->pixel_shift : 0;
298
2/2
✓ Branch 0 taken 2160 times.
✓ Branch 1 taken 451 times.
2611 const int chroma_idc = sps ? sps->r->sps_chroma_format_idc : 0;
299
2/2
✓ Branch 0 taken 2160 times.
✓ Branch 1 taken 451 times.
2611 const int has_ibc = sps ? sps->r->sps_ibc_enabled_flag : 0;
300 7590 const int changed = fc->tab.sz.chroma_format_idc != chroma_idc ||
301
2/2
✓ Branch 0 taken 2358 times.
✓ Branch 1 taken 10 times.
2368 fc->tab.sz.ctu_height != ctu_height ||
302
4/4
✓ Branch 0 taken 2368 times.
✓ Branch 1 taken 243 times.
✓ Branch 2 taken 451 times.
✓ Branch 3 taken 1907 times.
5430 fc->tab.sz.ctu_size != ctu_size ||
303
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 451 times.
451 fc->tab.sz.pixel_shift != ps;
304
305
2/2
✓ Branch 0 taken 2160 times.
✓ Branch 1 taken 451 times.
2611 fc->tab.sz.ibc_buffer_width = ctu_size ? 2 * MAX_CTU_SIZE * MAX_CTU_SIZE / ctu_size : 0;
306
307 2611 tl_init(l, has_ibc, changed);
308
309
2/2
✓ Branch 0 taken 7833 times.
✓ Branch 1 taken 2611 times.
10444 for (int i = LUMA; i < VVC_MAX_SAMPLE_ARRAYS; i++) {
310
2/2
✓ Branch 0 taken 6480 times.
✓ Branch 1 taken 1353 times.
7833 const int hs = sps ? sps->hshift[i] : 0;
311
2/2
✓ Branch 0 taken 6480 times.
✓ Branch 1 taken 1353 times.
7833 const int vs = sps ? sps->vshift[i] : 0;
312
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7833 times.
7833 TL_ADD(ibc_vir_buf[i], fc->tab.sz.ibc_buffer_width * ctu_size * ctu_height << ps >> hs >> vs);
313 }
314 2611 }
315
316 typedef void (*tl_init_fn)(TabList *l, VVCFrameContext *fc);
317
318 2611 static int frame_context_for_each_tl(VVCFrameContext *fc, int (*unary_fn)(TabList *l))
319 {
320 2611 const tl_init_fn init[] = {
321 ctu_nz_tl_init,
322 min_cb_tl_init,
323 min_cb_nz_tl_init,
324 min_pu_tl_init,
325 min_pu_nz_tl_init,
326 min_tu_tl_init,
327 min_tu_nz_tl_init,
328 pixel_buffer_nz_tl_init,
329 msm_tl_init,
330 ispmf_tl_init,
331 ibc_tl_init,
332 };
333
334
2/2
✓ Branch 0 taken 28721 times.
✓ Branch 1 taken 2611 times.
31332 for (int i = 0; i < FF_ARRAY_ELEMS(init); i++) {
335 TabList l;
336 int ret;
337
338 28721 init[i](&l, fc);
339 28721 ret = unary_fn(&l);
340
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 28721 times.
28721 if (ret < 0)
341 return ret;
342 }
343 2611 return 0;
344 }
345
346 1665 static void free_cus(VVCFrameContext *fc)
347 {
348
2/2
✓ Branch 0 taken 961 times.
✓ Branch 1 taken 704 times.
1665 if (fc->tab.cus) {
349
2/2
✓ Branch 0 taken 46833 times.
✓ Branch 1 taken 961 times.
47794 for (int i = 0; i < fc->tab.sz.ctu_count; i++)
350 46833 ff_vvc_ctu_free_cus(fc->tab.cus + i);
351 }
352 1665 }
353
354 704 static void pic_arrays_free(VVCFrameContext *fc)
355 {
356 704 free_cus(fc);
357 704 frame_context_for_each_tl(fc, tl_free);
358 704 av_refstruct_pool_uninit(&fc->rpl_tab_pool);
359 704 av_refstruct_pool_uninit(&fc->tab_dmvr_mvf_pool);
360
361 704 memset(&fc->tab.sz, 0, sizeof(fc->tab.sz));
362 704 }
363
364 961 static int pic_arrays_init(VVCContext *s, VVCFrameContext *fc)
365 {
366 961 const VVCSPS *sps = fc->ps.sps;
367 961 const VVCPPS *pps = fc->ps.pps;
368 961 const int ctu_count = pps->ctb_count;
369 961 const int pic_size_in_min_pu = pps->min_pu_width * pps->min_pu_height;
370 int ret;
371
372 961 free_cus(fc);
373
374 961 ret = frame_context_for_each_tl(fc, tl_create);
375
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 961 times.
961 if (ret < 0)
376 return ret;
377
378 // for error handling case, we may call free_cus before VVC_TASK_STAGE_INIT, so we need to set cus to 0 here
379 961 memset(fc->tab.cus, 0, sizeof(*fc->tab.cus) * ctu_count);
380
381 961 memset(fc->tab.slice_idx, -1, sizeof(*fc->tab.slice_idx) * ctu_count);
382
383
2/2
✓ Branch 0 taken 253 times.
✓ Branch 1 taken 708 times.
961 if (fc->tab.sz.ctu_count != ctu_count) {
384 253 av_refstruct_pool_uninit(&fc->rpl_tab_pool);
385 253 fc->rpl_tab_pool = av_refstruct_pool_alloc(ctu_count * sizeof(RefPicListTab), 0);
386
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 253 times.
253 if (!fc->rpl_tab_pool)
387 return AVERROR(ENOMEM);
388 }
389
390
2/2
✓ Branch 0 taken 253 times.
✓ Branch 1 taken 708 times.
961 if (fc->tab.sz.pic_size_in_min_pu != pic_size_in_min_pu) {
391 253 av_refstruct_pool_uninit(&fc->tab_dmvr_mvf_pool);
392 253 fc->tab_dmvr_mvf_pool = av_refstruct_pool_alloc(
393 pic_size_in_min_pu * sizeof(MvField), AV_REFSTRUCT_POOL_FLAG_ZERO_EVERY_TIME);
394
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 253 times.
253 if (!fc->tab_dmvr_mvf_pool)
395 return AVERROR(ENOMEM);
396 }
397
398 961 fc->tab.sz.ctu_count = pps->ctb_count;
399 961 fc->tab.sz.ctu_size = 1 << sps->ctb_log2_size_y << sps->ctb_log2_size_y;
400 961 fc->tab.sz.pic_size_in_min_cb = pps->min_cb_width * pps->min_cb_height;
401 961 fc->tab.sz.pic_size_in_min_pu = pic_size_in_min_pu;
402 961 fc->tab.sz.pic_size_in_min_tu = pps->min_tu_width * pps->min_tu_height;
403 961 fc->tab.sz.width = pps->width;
404 961 fc->tab.sz.height = pps->height;
405 961 fc->tab.sz.ctu_width = pps->ctb_width;
406 961 fc->tab.sz.ctu_height = pps->ctb_height;
407 961 fc->tab.sz.chroma_format_idc = sps->r->sps_chroma_format_idc;
408 961 fc->tab.sz.pixel_shift = sps->pixel_shift;
409
410 961 return 0;
411 }
412
413 946 int ff_vvc_per_frame_init(VVCFrameContext *fc)
414 {
415 946 return frame_context_for_each_tl(fc, tl_zero);
416 }
417
418 3189 static int min_positive(const int idx, const int diff, const int min_diff)
419 {
420
6/6
✓ Branch 0 taken 2718 times.
✓ Branch 1 taken 471 times.
✓ Branch 2 taken 1094 times.
✓ Branch 3 taken 1624 times.
✓ Branch 4 taken 18 times.
✓ Branch 5 taken 1076 times.
3189 return diff > 0 && (idx < 0 || diff < min_diff);
421 }
422
423 3197 static int max_negtive(const int idx, const int diff, const int max_diff)
424 {
425
6/6
✓ Branch 0 taken 1869 times.
✓ Branch 1 taken 1328 times.
✓ Branch 2 taken 707 times.
✓ Branch 3 taken 1162 times.
✓ Branch 4 taken 5 times.
✓ Branch 5 taken 702 times.
3197 return diff < 0 && (idx < 0 || diff > max_diff);
426 }
427
428 typedef int (*smvd_find_fxn)(const int idx, const int diff, const int old_diff);
429
430 3372 static int8_t smvd_find(const VVCFrameContext *fc, const SliceContext *sc, int lx, smvd_find_fxn find)
431 {
432 3372 const H266RawSliceHeader *rsh = sc->sh.r;
433 3372 const RefPicList *rpl = sc->rpl + lx;
434 3372 const int poc = fc->ref->poc;
435 3372 int8_t idx = -1;
436 3372 int old_diff = -1;
437
2/2
✓ Branch 0 taken 6923 times.
✓ Branch 1 taken 3372 times.
10295 for (int i = 0; i < rsh->num_ref_idx_active[lx]; i++) {
438
2/2
✓ Branch 0 taken 6386 times.
✓ Branch 1 taken 537 times.
6923 if (!rpl->refs[i].is_lt) {
439 6386 int diff = poc - rpl->refs[i].poc;
440
2/2
✓ Branch 1 taken 2809 times.
✓ Branch 2 taken 3577 times.
6386 if (find(idx, diff, old_diff)) {
441 2809 idx = i;
442 2809 old_diff = diff;
443 }
444 }
445 }
446 3372 return idx;
447 }
448
449 1434 static void smvd_ref_idx(const VVCFrameContext *fc, SliceContext *sc)
450 {
451 1434 VVCSH *sh = &sc->sh;
452
2/2
✓ Branch 0 taken 1400 times.
✓ Branch 1 taken 34 times.
1434 if (IS_B(sh->r)) {
453 1400 sh->ref_idx_sym[0] = smvd_find(fc, sc, 0, min_positive);
454 1400 sh->ref_idx_sym[1] = smvd_find(fc, sc, 1, max_negtive);
455
4/4
✓ Branch 0 taken 1369 times.
✓ Branch 1 taken 31 times.
✓ Branch 2 taken 255 times.
✓ Branch 3 taken 1114 times.
1400 if (sh->ref_idx_sym[0] == -1 || sh->ref_idx_sym[1] == -1) {
456 286 sh->ref_idx_sym[0] = smvd_find(fc, sc, 0, max_negtive);
457 286 sh->ref_idx_sym[1] = smvd_find(fc, sc, 1, min_positive);
458 }
459 }
460 1434 }
461
462 1470 static void eps_free(SliceContext *slice)
463 {
464 1470 av_freep(&slice->eps);
465 1470 slice->nb_eps = 0;
466 1470 }
467
468 704 static void slices_free(VVCFrameContext *fc)
469 {
470
2/2
✓ Branch 0 taken 253 times.
✓ Branch 1 taken 451 times.
704 if (fc->slices) {
471
2/2
✓ Branch 0 taken 785 times.
✓ Branch 1 taken 253 times.
1038 for (int i = 0; i < fc->nb_slices_allocated; i++) {
472 785 SliceContext *slice = fc->slices[i];
473
1/2
✓ Branch 0 taken 785 times.
✗ Branch 1 not taken.
785 if (slice) {
474 785 av_refstruct_unref(&slice->ref);
475 785 av_refstruct_unref(&slice->sh.r);
476 785 eps_free(slice);
477 785 av_free(slice);
478 }
479 }
480 253 av_freep(&fc->slices);
481 }
482 704 fc->nb_slices_allocated = 0;
483 704 fc->nb_slices = 0;
484 704 }
485
486 1726 static int slices_realloc(VVCFrameContext *fc)
487 {
488 void *p;
489 1726 const int size = (fc->nb_slices_allocated + 1) * 3 / 2;
490
491
2/2
✓ Branch 0 taken 1363 times.
✓ Branch 1 taken 363 times.
1726 if (fc->nb_slices < fc->nb_slices_allocated)
492 1363 return 0;
493
494 363 p = av_realloc_array(fc->slices, size, sizeof(*fc->slices));
495
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 363 times.
363 if (!p)
496 return AVERROR(ENOMEM);
497
498 363 fc->slices = p;
499
2/2
✓ Branch 0 taken 785 times.
✓ Branch 1 taken 363 times.
1148 for (int i = fc->nb_slices_allocated; i < size; i++) {
500 785 fc->slices[i] = av_mallocz(sizeof(*fc->slices[0]));
501
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 785 times.
785 if (!fc->slices[i]) {
502 fc->nb_slices_allocated = i;
503 return AVERROR(ENOMEM);
504 }
505 785 fc->slices[i]->slice_idx = i;
506 }
507 363 fc->nb_slices_allocated = size;
508
509 363 return 0;
510 }
511
512 2084 static int get_ep_size(const H266RawSliceHeader *rsh, GetBitContext *gb, const H2645NAL *nal, const int header_size, const int ep_index)
513 {
514 int size;
515
516
2/2
✓ Branch 0 taken 373 times.
✓ Branch 1 taken 1711 times.
2084 if (ep_index < rsh->num_entry_points) {
517 373 int skipped = 0;
518 373 int64_t start = (gb->index >> 3);
519 373 int64_t end = start + rsh->sh_entry_point_offset_minus1[ep_index] + 1;
520
3/4
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 367 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
373 while (skipped < nal->skipped_bytes && nal->skipped_bytes_pos[skipped] <= start + header_size) {
521 skipped++;
522 }
523
3/4
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 367 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
373 while (skipped < nal->skipped_bytes && nal->skipped_bytes_pos[skipped] <= end + header_size) {
524 end--;
525 skipped++;
526 }
527 373 size = end - start;
528 373 size = av_clip(size, 0, get_bits_left(gb) / 8);
529 } else {
530 1711 size = get_bits_left(gb) / 8;
531 }
532 2084 return size;
533 }
534
535 2084 static int ep_init_cabac_decoder(EntryPoint *ep, GetBitContext *gb, const int size)
536 {
537 int ret;
538
539
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2084 times.
2084 av_assert0(gb->buffer + get_bits_count(gb) / 8 + size <= gb->buffer_end);
540 2084 ret = ff_init_cabac_decoder (&ep->cc, gb->buffer + get_bits_count(gb) / 8, size);
541
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2084 times.
2084 if (ret < 0)
542 return ret;
543 2084 skip_bits(gb, size * 8);
544 2084 return 0;
545 }
546
547 2084 static int ep_init(EntryPoint *ep, const int ctu_addr, const int ctu_end, GetBitContext *gb, const int size)
548 {
549 2084 const int ret = ep_init_cabac_decoder(ep, gb, size);
550
551
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2084 times.
2084 if (ret < 0)
552 return ret;
553
554 2084 ep->ctu_start = ctu_addr;
555 2084 ep->ctu_end = ctu_end;
556
557
2/2
✓ Branch 0 taken 6252 times.
✓ Branch 1 taken 2084 times.
8336 for (int c_idx = LUMA; c_idx <= CR; c_idx++)
558 6252 ep->pp[c_idx].size = 0;
559
560 2084 return 0;
561 }
562
563 1711 static int slice_init_entry_points(SliceContext *sc,
564 VVCFrameContext *fc, const H2645NAL *nal, const CodedBitstreamUnit *unit)
565 {
566 1711 const VVCSH *sh = &sc->sh;
567 1711 const H266RawSlice *slice = unit->content_ref;
568 1711 int nb_eps = sh->r->num_entry_points + 1;
569 1711 int ctu_addr = 0;
570 GetBitContext gb;
571 int ret;
572
573
2/2
✓ Branch 0 taken 685 times.
✓ Branch 1 taken 1026 times.
1711 if (sc->nb_eps != nb_eps) {
574 685 eps_free(sc);
575 685 sc->eps = av_calloc(nb_eps, sizeof(*sc->eps));
576
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 685 times.
685 if (!sc->eps)
577 return AVERROR(ENOMEM);
578 685 sc->nb_eps = nb_eps;
579 }
580
581 1711 ret = init_get_bits8(&gb, slice->data, slice->data_size);
582
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1711 times.
1711 if (ret < 0)
583 return ret;
584
2/2
✓ Branch 0 taken 2084 times.
✓ Branch 1 taken 1711 times.
3795 for (int i = 0; i < sc->nb_eps; i++)
585 {
586 2084 const int size = get_ep_size(sc->sh.r, &gb, nal, slice->header_size, i);
587
2/2
✓ Branch 0 taken 1711 times.
✓ Branch 1 taken 373 times.
2084 const int ctu_end = (i + 1 == sc->nb_eps ? sh->num_ctus_in_curr_slice : sh->entry_point_start_ctu[i]);
588 2084 EntryPoint *ep = sc->eps + i;
589
590 2084 ret = ep_init(ep, ctu_addr, ctu_end, &gb, size);
591
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2084 times.
2084 if (ret < 0)
592 return ret;
593
594
2/2
✓ Branch 0 taken 46713 times.
✓ Branch 1 taken 2084 times.
48797 for (int j = ep->ctu_start; j < ep->ctu_end; j++) {
595 46713 const int rs = sc->sh.ctb_addr_in_curr_slice[j];
596 46713 fc->tab.slice_idx[rs] = sc->slice_idx;
597 }
598
599
2/2
✓ Branch 0 taken 373 times.
✓ Branch 1 taken 1711 times.
2084 if (i + 1 < sc->nb_eps)
600 373 ctu_addr = sh->entry_point_start_ctu[i];
601 }
602
603 1711 return 0;
604 }
605
606 2980 static VVCFrameContext* get_frame_context(const VVCContext *s, const VVCFrameContext *fc, const int delta)
607 {
608 2980 const int size = s->nb_fcs;
609 2980 const int idx = (fc - s->fcs + delta + size) % size;
610 2980 return s->fcs + idx;
611 }
612
613 4441 static int ref_frame(VVCFrame *dst, const VVCFrame *src)
614 {
615 int ret;
616
617 4441 ret = av_frame_ref(dst->frame, src->frame);
618
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4441 times.
4441 if (ret < 0)
619 return ret;
620
621 4441 av_refstruct_replace(&dst->sps, src->sps);
622 4441 av_refstruct_replace(&dst->pps, src->pps);
623
624
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4441 times.
4441 if (src->needs_fg) {
625 ret = av_frame_ref(dst->frame_grain, src->frame_grain);
626 if (ret < 0)
627 return ret;
628
629 dst->needs_fg = src->needs_fg;
630 }
631
632 4441 av_refstruct_replace(&dst->progress, src->progress);
633
634 4441 av_refstruct_replace(&dst->tab_dmvr_mvf, src->tab_dmvr_mvf);
635
636 4441 av_refstruct_replace(&dst->rpl_tab, src->rpl_tab);
637 4441 av_refstruct_replace(&dst->rpl, src->rpl);
638 4441 av_refstruct_replace(&dst->hwaccel_picture_private,
639 4441 src->hwaccel_picture_private);
640 4441 dst->nb_rpl_elems = src->nb_rpl_elems;
641
642 4441 dst->poc = src->poc;
643 4441 dst->ctb_count = src->ctb_count;
644
645 4441 dst->scaling_win = src->scaling_win;
646 4441 dst->ref_width = src->ref_width;
647 4441 dst->ref_height = src->ref_height;
648
649 4441 dst->flags = src->flags;
650 4441 dst->sequence = src->sequence;
651
652 4441 return 0;
653 }
654
655 704 static av_cold void frame_context_free(VVCFrameContext *fc)
656 {
657 704 slices_free(fc);
658
659 704 av_refstruct_pool_uninit(&fc->tu_pool);
660 704 av_refstruct_pool_uninit(&fc->cu_pool);
661
662
2/2
✓ Branch 0 taken 11968 times.
✓ Branch 1 taken 704 times.
12672 for (int i = 0; i < FF_ARRAY_ELEMS(fc->DPB); i++) {
663 11968 ff_vvc_unref_frame(fc, &fc->DPB[i], ~0);
664 11968 av_frame_free(&fc->DPB[i].frame);
665 11968 av_frame_free(&fc->DPB[i].frame_grain);
666 }
667
668 704 ff_vvc_frame_thread_free(fc);
669 704 pic_arrays_free(fc);
670 704 av_frame_free(&fc->output_frame);
671 704 ff_vvc_frame_ps_free(&fc->ps);
672 704 ff_vvc_sei_reset(&fc->sei);
673 704 }
674
675 704 static av_cold int frame_context_init(VVCFrameContext *fc, AVCodecContext *avctx)
676 {
677
678 704 fc->log_ctx = avctx;
679
680 704 fc->output_frame = av_frame_alloc();
681
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 704 times.
704 if (!fc->output_frame)
682 return AVERROR(ENOMEM);
683
684
2/2
✓ Branch 0 taken 11968 times.
✓ Branch 1 taken 704 times.
12672 for (int j = 0; j < FF_ARRAY_ELEMS(fc->DPB); j++) {
685 11968 fc->DPB[j].frame = av_frame_alloc();
686
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11968 times.
11968 if (!fc->DPB[j].frame)
687 return AVERROR(ENOMEM);
688
689 11968 fc->DPB[j].frame_grain = av_frame_alloc();
690
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11968 times.
11968 if (!fc->DPB[j].frame_grain)
691 return AVERROR(ENOMEM);
692 }
693 704 fc->cu_pool = av_refstruct_pool_alloc(sizeof(CodingUnit), 0);
694
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 704 times.
704 if (!fc->cu_pool)
695 return AVERROR(ENOMEM);
696
697 704 fc->tu_pool = av_refstruct_pool_alloc(sizeof(TransformUnit), 0);
698
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 704 times.
704 if (!fc->tu_pool)
699 return AVERROR(ENOMEM);
700
701 704 return 0;
702 }
703
704 961 static int frame_context_setup(VVCFrameContext *fc, VVCContext *s)
705 {
706 int ret;
707
708 // copy refs from the last frame
709
3/4
✓ Branch 0 taken 873 times.
✓ Branch 1 taken 88 times.
✓ Branch 2 taken 873 times.
✗ Branch 3 not taken.
961 if (s->nb_frames && s->nb_fcs > 1) {
710 873 VVCFrameContext *prev = get_frame_context(s, fc, -1);
711
2/2
✓ Branch 0 taken 14841 times.
✓ Branch 1 taken 873 times.
15714 for (int i = 0; i < FF_ARRAY_ELEMS(fc->DPB); i++) {
712 14841 ff_vvc_unref_frame(fc, &fc->DPB[i], ~0);
713
2/2
✓ Branch 0 taken 4441 times.
✓ Branch 1 taken 10400 times.
14841 if (prev->DPB[i].frame->buf[0]) {
714 4441 ret = ref_frame(&fc->DPB[i], &prev->DPB[i]);
715
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4441 times.
4441 if (ret < 0)
716 return ret;
717 }
718 }
719
720 873 ret = ff_vvc_sei_replace(&fc->sei, &prev->sei);
721
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 873 times.
873 if (ret < 0)
722 return ret;
723 }
724
725
4/4
✓ Branch 0 taken 954 times.
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 90 times.
✓ Branch 3 taken 864 times.
961 if (IS_IDR(s)) {
726 97 s->seq_decode = (s->seq_decode + 1) & 0xff;
727 97 ff_vvc_clear_refs(fc);
728 }
729
730 961 ret = pic_arrays_init(s, fc);
731
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 961 times.
961 if (ret < 0)
732 return ret;
733 961 ff_vvc_dsp_init(&fc->vvcdsp, fc->ps.sps->bit_depth);
734 961 ff_videodsp_init(&fc->vdsp, fc->ps.sps->bit_depth);
735 961 return 0;
736 }
737
738 /* SEI does not affect decoding, so we ignore the return value */
739 961 static void decode_prefix_sei(VVCFrameContext *fc, VVCContext *s)
740 {
741 961 CodedBitstreamFragment *frame = &s->current_frame;
742
743
2/2
✓ Branch 0 taken 3645 times.
✓ Branch 1 taken 961 times.
4606 for (int i = 0; i < frame->nb_units; i++) {
744 3645 const CodedBitstreamUnit *unit = frame->units + i;
745
746
2/2
✓ Branch 0 taken 68 times.
✓ Branch 1 taken 3577 times.
3645 if (unit->type == VVC_PREFIX_SEI_NUT) {
747 68 int ret = ff_vvc_sei_decode(&fc->sei, unit->content_ref, fc);
748
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 68 times.
68 if (ret < 0)
749 return;
750 }
751 }
752 }
753
754 961 static int set_side_data(VVCContext *s, VVCFrameContext *fc)
755 {
756 961 AVFrame *out = fc->ref->frame;
757
758 1922 return ff_h2645_sei_to_frame(out, &fc->sei.common, AV_CODEC_ID_VVC, s->avctx,
759 961 NULL, fc->ps.sps->bit_depth, fc->ps.sps->bit_depth, fc->ref->poc);
760 }
761
762 961 static int check_film_grain(VVCContext *s, VVCFrameContext *fc)
763 {
764 int ret;
765
766 1922 fc->ref->needs_fg = (fc->sei.common.film_grain_characteristics &&
767 fc->sei.common.film_grain_characteristics->present ||
768
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 961 times.
961 fc->sei.common.aom_film_grain.enable) &&
769
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 961 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1922 !(s->avctx->export_side_data & AV_CODEC_EXPORT_DATA_FILM_GRAIN) &&
770 !s->avctx->hwaccel;
771
772
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 961 times.
961 if (fc->ref->needs_fg &&
773 (fc->sei.common.film_grain_characteristics &&
774 fc->sei.common.film_grain_characteristics->present &&
775 !ff_h274_film_grain_params_supported(fc->sei.common.film_grain_characteristics->model_id,
776 fc->ref->frame->format) ||
777 !av_film_grain_params_select(fc->ref->frame))) {
778 av_log_once(s->avctx, AV_LOG_WARNING, AV_LOG_DEBUG, &s->film_grain_warning_shown,
779 "Unsupported film grain parameters. Ignoring film grain.\n");
780 fc->ref->needs_fg = 0;
781 }
782
783
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 961 times.
961 if (fc->ref->needs_fg) {
784 fc->ref->frame_grain->format = fc->ref->frame->format;
785 fc->ref->frame_grain->width = fc->ref->frame->width;
786 fc->ref->frame_grain->height = fc->ref->frame->height;
787
788 ret = ff_thread_get_buffer(s->avctx, fc->ref->frame_grain, 0);
789 if (ret < 0)
790 return ret;
791
792 return av_frame_copy_props(fc->ref->frame_grain, fc->ref->frame);
793 }
794
795 961 return 0;
796 }
797
798 961 static int frame_start(VVCContext *s, VVCFrameContext *fc, SliceContext *sc)
799 {
800 961 const VVCPH *ph = &fc->ps.ph;
801 961 const H266RawSliceHeader *rsh = sc->sh.r;
802 int ret;
803
804 // 8.3.1 Decoding process for picture order count
805
6/8
✓ Branch 0 taken 221 times.
✓ Branch 1 taken 740 times.
✓ Branch 2 taken 209 times.
✓ Branch 3 taken 12 times.
✓ Branch 4 taken 209 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 209 times.
✗ Branch 7 not taken.
961 if (!s->temporal_id && !ph->r->ph_non_ref_pic_flag && !(IS_RASL(s) || IS_RADL(s)))
806 209 s->poc_tid0 = ph->poc;
807
808
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 961 times.
961 if ((ret = ff_vvc_set_new_ref(s, fc, &fc->frame)) < 0)
809 goto fail;
810
811 961 decode_prefix_sei(fc, s);
812
813 961 ret = set_side_data(s, fc);
814
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 961 times.
961 if (ret < 0)
815 goto fail;
816
817 961 ret = check_film_grain(s, fc);
818
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 961 times.
961 if (ret < 0)
819 goto fail;
820
821
4/4
✓ Branch 0 taken 954 times.
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 864 times.
✓ Branch 3 taken 90 times.
961 if (!IS_IDR(s))
822 864 ff_vvc_bump_frame(s, fc);
823
824 961 av_frame_unref(fc->output_frame);
825
826
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 961 times.
961 if ((ret = ff_vvc_output_frame(s, fc, fc->output_frame,rsh->sh_no_output_of_prior_pics_flag, 0)) < 0)
827 goto fail;
828
829
2/2
✓ Branch 1 taken 15 times.
✓ Branch 2 taken 946 times.
961 if ((ret = ff_vvc_frame_rpl(s, fc, sc)) < 0)
830 15 goto fail;
831
832
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 946 times.
946 if ((ret = ff_vvc_frame_thread_init(fc)) < 0)
833 goto fail;
834 946 return 0;
835 15 fail:
836
1/2
✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
15 if (fc->ref)
837 15 ff_vvc_unref_frame(fc, fc->ref, ~0);
838 15 fc->ref = NULL;
839 15 return ret;
840 }
841
842 1726 static int slice_start(SliceContext *sc, VVCContext *s, VVCFrameContext *fc,
843 const CodedBitstreamUnit *unit, const int is_first_slice)
844 {
845 1726 VVCSH *sh = &sc->sh;
846 int ret;
847
848 1726 ret = ff_vvc_decode_sh(sh, &fc->ps, unit);
849
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1726 times.
1726 if (ret < 0)
850 return ret;
851
852 1726 av_refstruct_replace(&sc->ref, unit->content_ref);
853
854
2/2
✓ Branch 0 taken 961 times.
✓ Branch 1 taken 765 times.
1726 if (is_first_slice) {
855 961 ret = frame_start(s, fc, sc);
856
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 946 times.
961 if (ret < 0)
857 15 return ret;
858
1/2
✓ Branch 0 taken 765 times.
✗ Branch 1 not taken.
765 } else if (fc->ref) {
859
2/2
✓ Branch 0 taken 599 times.
✓ Branch 1 taken 166 times.
765 if (!IS_I(sh->r)) {
860 599 ret = ff_vvc_slice_rpl(s, fc, sc);
861
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 599 times.
599 if (ret < 0) {
862 av_log(fc->log_ctx, AV_LOG_WARNING,
863 "Error constructing the reference lists for the current slice.\n");
864 return ret;
865 }
866 }
867 } else {
868 av_log(fc->log_ctx, AV_LOG_ERROR, "First slice in a frame missing.\n");
869 return ret;
870 }
871
872
2/2
✓ Branch 0 taken 1434 times.
✓ Branch 1 taken 277 times.
1711 if (!IS_I(sh->r))
873 1434 smvd_ref_idx(fc, sc);
874
875 1711 return 0;
876 }
877
878 89 static enum AVPixelFormat get_format(AVCodecContext *avctx, const VVCSPS *sps)
879 {
880 #define HWACCEL_MAX CONFIG_VVC_VAAPI_HWACCEL
881
882 89 enum AVPixelFormat pix_fmts[HWACCEL_MAX + 2], *fmt = pix_fmts;
883
884
3/3
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 78 times.
✓ Branch 2 taken 6 times.
89 switch (sps->pix_fmt) {
885 5 case AV_PIX_FMT_YUV420P:
886 #if CONFIG_VVC_VAAPI_HWACCEL
887 5 *fmt++ = AV_PIX_FMT_VAAPI;
888 #endif
889 5 break;
890 78 case AV_PIX_FMT_YUV420P10:
891 #if CONFIG_VVC_VAAPI_HWACCEL
892 78 *fmt++ = AV_PIX_FMT_VAAPI;
893 #endif
894 78 break;
895 }
896
897 89 *fmt++ = sps->pix_fmt;
898 89 *fmt = AV_PIX_FMT_NONE;
899
900 89 return ff_get_format(avctx, pix_fmts);
901 }
902
903 961 static int export_frame_params(VVCContext *s, const VVCFrameContext *fc)
904 {
905 961 AVCodecContext *c = s->avctx;
906 961 const VVCSPS *sps = fc->ps.sps;
907 961 const VVCPPS *pps = fc->ps.pps;
908
909 // Reset the format if pix_fmt/w/h change.
910
5/6
✓ Branch 0 taken 873 times.
✓ Branch 1 taken 88 times.
✓ Branch 2 taken 872 times.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 872 times.
961 if (c->sw_pix_fmt != sps->pix_fmt || c->coded_width != pps->width || c->coded_height != pps->height) {
911 89 c->coded_width = pps->width;
912 89 c->coded_height = pps->height;
913 89 c->sw_pix_fmt = sps->pix_fmt;
914 89 c->pix_fmt = get_format(c, sps);
915
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 89 times.
89 if (c->pix_fmt < 0)
916 return AVERROR_INVALIDDATA;
917 }
918
919 961 c->width = pps->width - ((pps->r->pps_conf_win_left_offset + pps->r->pps_conf_win_right_offset) << sps->hshift[CHROMA]);
920 961 c->height = pps->height - ((pps->r->pps_conf_win_top_offset + pps->r->pps_conf_win_bottom_offset) << sps->vshift[CHROMA]);
921
922 961 return 0;
923 }
924
925 961 static int frame_setup(VVCFrameContext *fc, VVCContext *s)
926 {
927 961 int ret = ff_vvc_decode_frame_ps(&fc->ps, s);
928
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 961 times.
961 if (ret < 0)
929 return ret;
930
931 961 ret = frame_context_setup(fc, s);
932
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 961 times.
961 if (ret < 0)
933 return ret;
934
935 961 ret = export_frame_params(s, fc);
936
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 961 times.
961 if (ret < 0)
937 return ret;
938
939 961 return 0;
940 }
941
942 1726 static int decode_slice(VVCContext *s, VVCFrameContext *fc, AVBufferRef *buf_ref,
943 const H2645NAL *nal, const CodedBitstreamUnit *unit)
944 {
945 int ret;
946 SliceContext *sc;
947 1726 const int is_first_slice = !fc->nb_slices;
948
949 1726 ret = slices_realloc(fc);
950
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1726 times.
1726 if (ret < 0)
951 return ret;
952
953 1726 sc = fc->slices[fc->nb_slices];
954
955 1726 s->vcl_unit_type = nal->type;
956
2/2
✓ Branch 0 taken 961 times.
✓ Branch 1 taken 765 times.
1726 if (is_first_slice) {
957 961 ret = frame_setup(fc, s);
958
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 961 times.
961 if (ret < 0)
959 return ret;
960 }
961
962 1726 ret = slice_start(sc, s, fc, unit, is_first_slice);
963
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 1711 times.
1726 if (ret < 0)
964 15 return ret;
965
966 1711 ret = slice_init_entry_points(sc, fc, nal, unit);
967
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1711 times.
1711 if (ret < 0)
968 return ret;
969
970
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1711 times.
1711 if (s->avctx->hwaccel) {
971 if (is_first_slice) {
972 ret = FF_HW_CALL(s->avctx, start_frame, buf_ref, NULL, 0);
973 if (ret < 0)
974 return ret;
975 }
976
977 ret = FF_HW_CALL(s->avctx, decode_slice,
978 nal->raw_data, nal->raw_size);
979 if (ret < 0)
980 return ret;
981 }
982
983 1711 fc->nb_slices++;
984
985 1711 return 0;
986 }
987
988 3630 static int decode_nal_unit(VVCContext *s, VVCFrameContext *fc, AVBufferRef *buf_ref,
989 const H2645NAL *nal, const CodedBitstreamUnit *unit)
990 {
991 int ret;
992
993 3630 s->temporal_id = nal->temporal_id;
994
995
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3630 times.
3630 if (nal->nuh_layer_id > 0) {
996 avpriv_report_missing_feature(fc->log_ctx,
997 "Decoding of multilayer bitstreams");
998 return AVERROR_PATCHWELCOME;
999 }
1000
1001
6/6
✓ Branch 0 taken 442 times.
✓ Branch 1 taken 1726 times.
✓ Branch 2 taken 401 times.
✓ Branch 3 taken 68 times.
✓ Branch 4 taken 888 times.
✓ Branch 5 taken 105 times.
3630 switch (unit->type) {
1002 442 case VVC_VPS_NUT:
1003 case VVC_SPS_NUT:
1004 case VVC_PPS_NUT:
1005 /* vps, sps, sps cached by s->cbc */
1006 442 break;
1007 1726 case VVC_TRAIL_NUT:
1008 case VVC_STSA_NUT:
1009 case VVC_RADL_NUT:
1010 case VVC_RASL_NUT:
1011 case VVC_IDR_W_RADL:
1012 case VVC_IDR_N_LP:
1013 case VVC_CRA_NUT:
1014 case VVC_GDR_NUT:
1015 1726 ret = decode_slice(s, fc, buf_ref, nal, unit);
1016
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 1711 times.
1726 if (ret < 0)
1017 15 return ret;
1018 1711 break;
1019 401 case VVC_PREFIX_APS_NUT:
1020 case VVC_SUFFIX_APS_NUT:
1021 401 ret = ff_vvc_decode_aps(&s->ps, unit);
1022
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 401 times.
401 if (ret < 0)
1023 return ret;
1024 401 break;
1025 68 case VVC_PREFIX_SEI_NUT:
1026 /* handle by decode_prefix_sei() */
1027 68 break;
1028
1029 888 case VVC_SUFFIX_SEI_NUT:
1030 /* SEI does not affect decoding, so we ignore the return value*/
1031
1/2
✓ Branch 0 taken 888 times.
✗ Branch 1 not taken.
888 if (fc)
1032 888 ff_vvc_sei_decode(&fc->sei, unit->content_ref, fc);
1033 888 break;
1034 }
1035
1036 3615 return 0;
1037 }
1038
1039 961 static int decode_nal_units(VVCContext *s, VVCFrameContext *fc, AVPacket *avpkt)
1040 {
1041 961 const CodedBitstreamH266Context *h266 = s->cbc->priv_data;
1042 961 CodedBitstreamFragment *frame = &s->current_frame;
1043 961 int ret = 0;
1044 961 s->last_eos = s->eos;
1045 961 s->eos = 0;
1046 961 fc->ref = NULL;
1047
1048 961 ff_cbs_fragment_reset(frame);
1049 961 ret = ff_cbs_read_packet(s->cbc, frame, avpkt);
1050
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 961 times.
961 if (ret < 0) {
1051 av_log(s->avctx, AV_LOG_ERROR, "Failed to read packet.\n");
1052 return ret;
1053 }
1054 /* decode the NAL units */
1055
2/2
✓ Branch 0 taken 3630 times.
✓ Branch 1 taken 946 times.
4576 for (int i = 0; i < frame->nb_units; i++) {
1056 3630 const H2645NAL *nal = h266->common.read_packet.nals + i;
1057 3630 const CodedBitstreamUnit *unit = frame->units + i;
1058
1059
2/4
✓ Branch 0 taken 3630 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 3630 times.
3630 if (unit->type == VVC_EOB_NUT || unit->type == VVC_EOS_NUT) {
1060 s->last_eos = 1;
1061 } else {
1062 3630 ret = decode_nal_unit(s, fc, avpkt->buf, nal, unit);
1063
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 3615 times.
3630 if (ret < 0) {
1064 15 av_log(s->avctx, AV_LOG_WARNING,
1065 "Error parsing NAL unit #%d.\n", i);
1066 15 goto fail;
1067 }
1068 }
1069 }
1070 946 return 0;
1071
1072 15 fail:
1073
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15 times.
15 if (fc->ref)
1074 ff_vvc_report_frame_finished(fc->ref);
1075 15 return ret;
1076 }
1077
1078 946 static int frame_end(VVCContext *s, VVCFrameContext *fc)
1079 {
1080 const AVFilmGrainParams *fgp;
1081 int ret;
1082
1083
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 946 times.
946 if (fc->ref->needs_fg) {
1084 av_assert0(fc->ref->frame_grain->buf[0]);
1085 fgp = av_film_grain_params_select(fc->ref->frame);
1086 switch (fgp->type) {
1087 case AV_FILM_GRAIN_PARAMS_NONE:
1088 av_assert0(0);
1089 return AVERROR_BUG;
1090 case AV_FILM_GRAIN_PARAMS_H274:
1091 ret = ff_h274_apply_film_grain(fc->ref->frame_grain, fc->ref->frame,
1092 &s->h274db, fgp);
1093 if (ret < 0)
1094 return ret;
1095 break;
1096 case AV_FILM_GRAIN_PARAMS_AV1:
1097 ret = ff_aom_apply_film_grain(fc->ref->frame_grain, fc->ref->frame, fgp);
1098 if (ret < 0)
1099 return ret;
1100 break;
1101 }
1102 }
1103
1104
2/4
✓ Branch 0 taken 946 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 946 times.
946 if (!s->avctx->hwaccel && s->avctx->err_recognition & AV_EF_CRCCHECK) {
1105 VVCSEI *sei = &fc->sei;
1106 if (sei->picture_hash.present) {
1107 ret = ff_h274_hash_init(&s->hash_ctx, sei->picture_hash.hash_type);
1108 if (ret < 0)
1109 return ret;
1110
1111 ret = ff_h274_hash_verify(s->hash_ctx, &sei->picture_hash, fc->ref->frame, fc->ps.pps->width, fc->ps.pps->height);
1112 if (ret < 0) {
1113 av_log(s->avctx, AV_LOG_ERROR,
1114 "Verifying checksum for frame with decoder_order %d: failed\n",
1115 (int)fc->decode_order);
1116 if (s->avctx->err_recognition & AV_EF_EXPLODE)
1117 return ret;
1118 }
1119 }
1120 }
1121
1122 946 return 0;
1123 }
1124
1125 946 static int wait_delayed_frame(VVCContext *s, AVFrame *output, int *got_output)
1126 {
1127 946 VVCFrameContext *delayed = get_frame_context(s, s->fcs, s->nb_frames - s->nb_delayed);
1128 946 int ret = ff_vvc_frame_wait(s, delayed);
1129
1130
1/2
✓ Branch 0 taken 946 times.
✗ Branch 1 not taken.
946 if (!ret) {
1131 946 ret = frame_end(s, delayed);
1132
5/6
✓ Branch 0 taken 946 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 822 times.
✓ Branch 3 taken 124 times.
✓ Branch 4 taken 804 times.
✓ Branch 5 taken 18 times.
946 if (ret >= 0 && delayed->output_frame->buf[0] && output) {
1133 804 av_frame_move_ref(output, delayed->output_frame);
1134 804 *got_output = 1;
1135 }
1136 }
1137 946 s->nb_delayed--;
1138
1139 946 return ret;
1140 }
1141
1142 946 static int submit_frame(VVCContext *s, VVCFrameContext *fc, AVFrame *output, int *got_output)
1143 {
1144 int ret;
1145
1146
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 946 times.
946 if (s->avctx->hwaccel) {
1147 if (ret = FF_HW_SIMPLE_CALL(s->avctx, end_frame) < 0) {
1148 av_log(s->avctx, AV_LOG_ERROR,
1149 "Hardware accelerator failed to decode picture\n");
1150 ff_vvc_unref_frame(fc, fc->ref, ~0);
1151 return ret;
1152 }
1153 } else {
1154
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 946 times.
946 if (ret = ff_vvc_frame_submit(s, fc) < 0) {
1155 ff_vvc_report_frame_finished(fc->ref);
1156 return ret;
1157 }
1158 }
1159
1160 946 s->nb_frames++;
1161 946 s->nb_delayed++;
1162
1163
3/4
✓ Branch 0 taken 231 times.
✓ Branch 1 taken 715 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 231 times.
946 if (s->nb_delayed >= s->nb_fcs || s->avctx->hwaccel) {
1164
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 715 times.
715 if ((ret = wait_delayed_frame(s, output, got_output)) < 0)
1165 return ret;
1166 }
1167 946 return 0;
1168 }
1169
1170 272 static int get_decoded_frame(VVCContext *s, AVFrame *output, int *got_output)
1171 {
1172 int ret;
1173
2/2
✓ Branch 0 taken 172 times.
✓ Branch 1 taken 112 times.
284 while (s->nb_delayed) {
1174
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 172 times.
172 if ((ret = wait_delayed_frame(s, output, got_output)) < 0)
1175 return ret;
1176
2/2
✓ Branch 0 taken 160 times.
✓ Branch 1 taken 12 times.
172 if (*got_output)
1177 160 return 0;
1178 }
1179
1/2
✓ Branch 0 taken 112 times.
✗ Branch 1 not taken.
112 if (s->nb_frames) {
1180 //we still have frames cached in dpb.
1181 112 VVCFrameContext *last = get_frame_context(s, s->fcs, s->nb_frames - 1);
1182
1183 112 ret = ff_vvc_output_frame(s, last, output, 0, 1);
1184
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 112 times.
112 if (ret < 0)
1185 return ret;
1186 112 *got_output = ret;
1187 }
1188 112 return 0;
1189 }
1190
1191 1233 static int vvc_decode_frame(AVCodecContext *avctx, AVFrame *output,
1192 int *got_output, AVPacket *avpkt)
1193 {
1194 1233 VVCContext *s = avctx->priv_data;
1195 VVCFrameContext *fc;
1196 int ret;
1197
1198
2/2
✓ Branch 0 taken 272 times.
✓ Branch 1 taken 961 times.
1233 if (!avpkt->size)
1199 272 return get_decoded_frame(s, output, got_output);
1200
1201 961 fc = get_frame_context(s, s->fcs, s->nb_frames);
1202
1203 961 fc->nb_slices = 0;
1204 961 fc->decode_order = s->nb_frames;
1205
1206 961 ret = decode_nal_units(s, fc, avpkt);
1207
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 946 times.
961 if (ret < 0)
1208 15 return ret;
1209
1210
2/4
✓ Branch 0 taken 946 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 946 times.
946 if (!fc->ft || !fc->ref)
1211 return avpkt->size;
1212
1213 946 ret = submit_frame(s, fc, output, got_output);
1214
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 946 times.
946 if (ret < 0)
1215 return ret;
1216
1217 946 return avpkt->size;
1218 }
1219
1220 88 static av_cold void vvc_decode_flush(AVCodecContext *avctx)
1221 {
1222 88 VVCContext *s = avctx->priv_data;
1223 88 int got_output = 0;
1224
1225
2/2
✓ Branch 0 taken 59 times.
✓ Branch 1 taken 88 times.
147 while (s->nb_delayed)
1226 59 wait_delayed_frame(s, NULL, &got_output);
1227
1228
1/2
✓ Branch 0 taken 88 times.
✗ Branch 1 not taken.
88 if (s->fcs) {
1229 88 VVCFrameContext *last = get_frame_context(s, s->fcs, s->nb_frames - 1);
1230 88 ff_vvc_flush_dpb(last);
1231 }
1232
1233 88 s->ps.sps_id_used = 0;
1234
1235 88 s->eos = 1;
1236 88 }
1237
1238 88 static av_cold int vvc_decode_free(AVCodecContext *avctx)
1239 {
1240 88 VVCContext *s = avctx->priv_data;
1241
1242 88 ff_cbs_fragment_free(&s->current_frame);
1243 88 vvc_decode_flush(avctx);
1244 88 ff_vvc_executor_free(&s->executor);
1245
1/2
✓ Branch 0 taken 88 times.
✗ Branch 1 not taken.
88 if (s->fcs) {
1246
2/2
✓ Branch 0 taken 704 times.
✓ Branch 1 taken 88 times.
792 for (int i = 0; i < s->nb_fcs; i++)
1247 704 frame_context_free(s->fcs + i);
1248 88 av_free(s->fcs);
1249 }
1250 88 ff_h274_hash_freep(&s->hash_ctx);
1251 88 ff_vvc_ps_uninit(&s->ps);
1252 88 ff_cbs_close(&s->cbc);
1253
1254 88 return 0;
1255 }
1256
1257 59 static av_cold void init_default_scale_m(void)
1258 {
1259 59 memset(&ff_vvc_default_scale_m, 16, sizeof(ff_vvc_default_scale_m));
1260 59 }
1261
1262 #define VVC_MAX_DELAYED_FRAMES 16
1263 88 static av_cold int vvc_decode_init(AVCodecContext *avctx)
1264 {
1265 88 VVCContext *s = avctx->priv_data;
1266 static AVOnce init_static_once = AV_ONCE_INIT;
1267 88 const int cpu_count = av_cpu_count();
1268 88 const int delayed = FFMIN(cpu_count, VVC_MAX_DELAYED_FRAMES);
1269
1/2
✓ Branch 0 taken 88 times.
✗ Branch 1 not taken.
88 int thread_count = avctx->thread_count ? avctx->thread_count : delayed;
1270 int ret;
1271
1272 88 s->avctx = avctx;
1273
1274 88 ret = ff_cbs_init(&s->cbc, AV_CODEC_ID_VVC, avctx);
1275
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 88 times.
88 if (ret)
1276 return ret;
1277
1278
3/4
✓ Branch 0 taken 31 times.
✓ Branch 1 taken 57 times.
✓ Branch 2 taken 31 times.
✗ Branch 3 not taken.
88 if (avctx->extradata_size > 0 && avctx->extradata) {
1279 31 ret = ff_cbs_read_extradata_from_codec(s->cbc, &s->current_frame, avctx);
1280
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 31 times.
31 if (ret < 0)
1281 return ret;
1282 }
1283
1284
1/2
✓ Branch 0 taken 88 times.
✗ Branch 1 not taken.
88 s->nb_fcs = (avctx->flags & AV_CODEC_FLAG_LOW_DELAY) ? 1 : delayed;
1285 88 s->fcs = av_calloc(s->nb_fcs, sizeof(*s->fcs));
1286
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 88 times.
88 if (!s->fcs)
1287 return AVERROR(ENOMEM);
1288
1289
2/2
✓ Branch 0 taken 704 times.
✓ Branch 1 taken 88 times.
792 for (int i = 0; i < s->nb_fcs; i++) {
1290 704 VVCFrameContext *fc = s->fcs + i;
1291 704 ret = frame_context_init(fc, avctx);
1292
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 704 times.
704 if (ret < 0)
1293 return ret;
1294 }
1295
1296
1/2
✓ Branch 0 taken 88 times.
✗ Branch 1 not taken.
88 if (thread_count == 1)
1297 88 thread_count = 0;
1298 88 s->executor = ff_vvc_executor_alloc(s, thread_count);
1299
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 88 times.
88 if (!s->executor)
1300 return AVERROR(ENOMEM);
1301
1302 88 s->eos = 1;
1303 88 GDR_SET_RECOVERED(s);
1304 88 ff_thread_once(&init_static_once, init_default_scale_m);
1305
1306 88 return 0;
1307 }
1308
1309 const FFCodec ff_vvc_decoder = {
1310 .p.name = "vvc",
1311 .p.long_name = NULL_IF_CONFIG_SMALL("VVC (Versatile Video Coding)"),
1312 .p.type = AVMEDIA_TYPE_VIDEO,
1313 .p.id = AV_CODEC_ID_VVC,
1314 .priv_data_size = sizeof(VVCContext),
1315 .init = vvc_decode_init,
1316 .close = vvc_decode_free,
1317 FF_CODEC_DECODE_CB(vvc_decode_frame),
1318 .flush = vvc_decode_flush,
1319 .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY | AV_CODEC_CAP_OTHER_THREADS,
1320 .caps_internal = FF_CODEC_CAP_EXPORTS_CROPPING | FF_CODEC_CAP_INIT_CLEANUP |
1321 FF_CODEC_CAP_AUTO_THREADS,
1322 .p.profiles = NULL_IF_CONFIG_SMALL(ff_vvc_profiles),
1323 .hw_configs = (const AVCodecHWConfigInternal *const []) {
1324 #if CONFIG_VVC_VAAPI_HWACCEL
1325 HWACCEL_VAAPI(vvc),
1326 #endif
1327 NULL
1328 },
1329 };
1330