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