FFmpeg coverage


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