FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/vvc/dec.c
Date: 2025-08-19 23:55:23
Exec Total Coverage
Lines: 649 766 84.7%
Functions: 56 56 100.0%
Branches: 387 565 68.5%

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