FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/vvc/dec.c
Date: 2024-07-16 12:46:59
Exec Total Coverage
Lines: 570 641 88.9%
Functions: 47 47 100.0%
Branches: 347 474 73.2%

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