Line | Branch | Exec | Source |
---|---|---|---|
1 | /* | ||
2 | * VVC parameter set parser | ||
3 | * | ||
4 | * Copyright (C) 2023 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 <stdbool.h> | ||
24 | |||
25 | #include "libavcodec/cbs_h266.h" | ||
26 | #include "libavcodec/decode.h" | ||
27 | #include "libavcodec/h2645data.h" | ||
28 | #include "libavutil/mem.h" | ||
29 | #include "libavutil/pixdesc.h" | ||
30 | #include "libavutil/refstruct.h" | ||
31 | #include "data.h" | ||
32 | #include "ps.h" | ||
33 | #include "dec.h" | ||
34 | |||
35 | 100 | static int sps_map_pixel_format(VVCSPS *sps, void *log_ctx) | |
36 | { | ||
37 | 100 | const H266RawSPS *r = sps->r; | |
38 | const AVPixFmtDescriptor *desc; | ||
39 | |||
40 |
2/4✓ Branch 0 taken 7 times.
✓ Branch 1 taken 93 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
100 | switch (sps->bit_depth) { |
41 | 7 | case 8: | |
42 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
|
7 | if (r->sps_chroma_format_idc == 0) sps->pix_fmt = AV_PIX_FMT_GRAY8; |
43 |
1/2✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
|
7 | if (r->sps_chroma_format_idc == 1) sps->pix_fmt = AV_PIX_FMT_YUV420P; |
44 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
|
7 | if (r->sps_chroma_format_idc == 2) sps->pix_fmt = AV_PIX_FMT_YUV422P; |
45 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
|
7 | if (r->sps_chroma_format_idc == 3) sps->pix_fmt = AV_PIX_FMT_YUV444P; |
46 | 7 | break; | |
47 | 93 | case 10: | |
48 |
2/2✓ Branch 0 taken 3 times.
✓ Branch 1 taken 90 times.
|
93 | if (r->sps_chroma_format_idc == 0) sps->pix_fmt = AV_PIX_FMT_GRAY10; |
49 |
2/2✓ Branch 0 taken 83 times.
✓ Branch 1 taken 10 times.
|
93 | if (r->sps_chroma_format_idc == 1) sps->pix_fmt = AV_PIX_FMT_YUV420P10; |
50 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 91 times.
|
93 | if (r->sps_chroma_format_idc == 2) sps->pix_fmt = AV_PIX_FMT_YUV422P10; |
51 |
2/2✓ Branch 0 taken 5 times.
✓ Branch 1 taken 88 times.
|
93 | if (r->sps_chroma_format_idc == 3) sps->pix_fmt = AV_PIX_FMT_YUV444P10; |
52 | 93 | break; | |
53 | ✗ | case 12: | |
54 | ✗ | if (r->sps_chroma_format_idc == 0) sps->pix_fmt = AV_PIX_FMT_GRAY12; | |
55 | ✗ | if (r->sps_chroma_format_idc == 1) sps->pix_fmt = AV_PIX_FMT_YUV420P12; | |
56 | ✗ | if (r->sps_chroma_format_idc == 2) sps->pix_fmt = AV_PIX_FMT_YUV422P12; | |
57 | ✗ | if (r->sps_chroma_format_idc == 3) sps->pix_fmt = AV_PIX_FMT_YUV444P12; | |
58 | ✗ | break; | |
59 | ✗ | default: | |
60 | ✗ | av_log(log_ctx, AV_LOG_ERROR, | |
61 | "The following bit-depths are currently specified: 8, 10, 12 bits, " | ||
62 | "chroma_format_idc is %d, depth is %d\n", | ||
63 | ✗ | r->sps_chroma_format_idc, sps->bit_depth); | |
64 | ✗ | return AVERROR_INVALIDDATA; | |
65 | } | ||
66 | |||
67 | 100 | desc = av_pix_fmt_desc_get(sps->pix_fmt); | |
68 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 100 times.
|
100 | if (!desc) |
69 | ✗ | return AVERROR(EINVAL); | |
70 | |||
71 | 100 | sps->hshift[0] = sps->vshift[0] = 0; | |
72 | 100 | sps->hshift[2] = sps->hshift[1] = desc->log2_chroma_w; | |
73 | 100 | sps->vshift[2] = sps->vshift[1] = desc->log2_chroma_h; | |
74 | |||
75 | 100 | sps->pixel_shift = sps->bit_depth > 8; | |
76 | |||
77 | 100 | return 0; | |
78 | } | ||
79 | |||
80 | 100 | static int sps_bit_depth(VVCSPS *sps, void *log_ctx) | |
81 | { | ||
82 | 100 | const H266RawSPS *r = sps->r; | |
83 | |||
84 | 100 | sps->bit_depth = r->sps_bitdepth_minus8 + 8; | |
85 | 100 | sps->qp_bd_offset = 6 * (sps->bit_depth - 8); | |
86 | 100 | sps->log2_transform_range = | |
87 |
1/6✗ Branch 0 not taken.
✓ Branch 1 taken 100 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
|
100 | r->sps_extended_precision_flag ? FFMAX(15, FFMIN(20, sps->bit_depth + 6)) : 15; |
88 | 100 | return sps_map_pixel_format(sps, log_ctx); | |
89 | } | ||
90 | |||
91 | 97 | static int sps_chroma_qp_table(VVCSPS *sps) | |
92 | { | ||
93 | 97 | const H266RawSPS *r = sps->r; | |
94 | 194 | const int num_qp_tables = r->sps_same_qp_table_for_chroma_flag ? | |
95 |
3/4✓ Branch 0 taken 3 times.
✓ Branch 1 taken 94 times.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
|
97 | 1 : (r->sps_joint_cbcr_enabled_flag ? 3 : 2); |
96 | |||
97 |
2/2✓ Branch 0 taken 103 times.
✓ Branch 1 taken 97 times.
|
200 | for (int i = 0; i < num_qp_tables; i++) { |
98 | int num_points_in_qp_table; | ||
99 | int8_t qp_in[VVC_MAX_POINTS_IN_QP_TABLE], qp_out[VVC_MAX_POINTS_IN_QP_TABLE]; | ||
100 | unsigned int delta_qp_in[VVC_MAX_POINTS_IN_QP_TABLE]; | ||
101 | 103 | int off = sps->qp_bd_offset; | |
102 | |||
103 | 103 | num_points_in_qp_table = r->sps_num_points_in_qp_table_minus1[i] + 1; | |
104 | |||
105 | 103 | qp_out[0] = qp_in[0] = r->sps_qp_table_start_minus26[i] + 26; | |
106 |
2/2✓ Branch 0 taken 317 times.
✓ Branch 1 taken 103 times.
|
420 | for (int j = 0; j < num_points_in_qp_table; j++ ) { |
107 | 317 | const uint8_t delta_qp_out = (r->sps_delta_qp_in_val_minus1[i][j] ^ r->sps_delta_qp_diff_val[i][j]); | |
108 | 317 | delta_qp_in[j] = r->sps_delta_qp_in_val_minus1[i][j] + 1; | |
109 | // Note: we cannot check qp_{in,out}[j+1] here as qp_*[j] + delta_qp_* | ||
110 | // may not fit in an 8-bit signed integer. | ||
111 |
2/4✓ Branch 0 taken 317 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 317 times.
|
317 | if (qp_in[j] + delta_qp_in[j] > 63 || qp_out[j] + delta_qp_out > 63) |
112 | ✗ | return AVERROR(EINVAL); | |
113 | 317 | qp_in[j+1] = qp_in[j] + delta_qp_in[j]; | |
114 | 317 | qp_out[j+1] = qp_out[j] + delta_qp_out; | |
115 | } | ||
116 | 103 | sps->chroma_qp_table[i][qp_in[0] + off] = qp_out[0]; | |
117 |
2/2✓ Branch 0 taken 3008 times.
✓ Branch 1 taken 103 times.
|
3111 | for (int k = qp_in[0] - 1 + off; k >= 0; k--) |
118 | 3008 | sps->chroma_qp_table[i][k] = av_clip(sps->chroma_qp_table[i][k+1]-1, -off, 63); | |
119 | |||
120 |
2/2✓ Branch 0 taken 317 times.
✓ Branch 1 taken 103 times.
|
420 | for (int j = 0; j < num_points_in_qp_table; j++) { |
121 | 317 | int sh = delta_qp_in[j] >> 1; | |
122 |
2/2✓ Branch 0 taken 2532 times.
✓ Branch 1 taken 317 times.
|
2849 | for (int k = qp_in[j] + 1 + off, m = 1; k <= qp_in[j+1] + off; k++, m++) { |
123 | 2532 | sps->chroma_qp_table[i][k] = sps->chroma_qp_table[i][qp_in[j] + off] + | |
124 | 2532 | ((qp_out[j+1] - qp_out[j]) * m + sh) / delta_qp_in[j]; | |
125 | } | ||
126 | } | ||
127 |
2/2✓ Branch 0 taken 2101 times.
✓ Branch 1 taken 103 times.
|
2204 | for (int k = qp_in[num_points_in_qp_table] + 1 + off; k <= 63 + off; k++) |
128 | 2101 | sps->chroma_qp_table[i][k] = av_clip(sps->chroma_qp_table[i][k-1] + 1, -sps->qp_bd_offset, 63); | |
129 | } | ||
130 |
2/2✓ Branch 0 taken 94 times.
✓ Branch 1 taken 3 times.
|
97 | if (r->sps_same_qp_table_for_chroma_flag) { |
131 | 94 | memcpy(&sps->chroma_qp_table[1], &sps->chroma_qp_table[0], sizeof(sps->chroma_qp_table[0])); | |
132 | 94 | memcpy(&sps->chroma_qp_table[2], &sps->chroma_qp_table[0], sizeof(sps->chroma_qp_table[0])); | |
133 | } | ||
134 | |||
135 | 97 | return 0; | |
136 | } | ||
137 | |||
138 | 100 | static void sps_poc(VVCSPS *sps) | |
139 | { | ||
140 | 100 | sps->max_pic_order_cnt_lsb = 1 << (sps->r->sps_log2_max_pic_order_cnt_lsb_minus4 + 4); | |
141 | 100 | } | |
142 | |||
143 | 100 | static void sps_inter(VVCSPS *sps) | |
144 | { | ||
145 | 100 | const H266RawSPS *r = sps->r; | |
146 | |||
147 | 100 | sps->max_num_merge_cand = 6 - r->sps_six_minus_max_num_merge_cand; | |
148 | 100 | sps->max_num_ibc_merge_cand = 6 - r->sps_six_minus_max_num_ibc_merge_cand; | |
149 | |||
150 |
2/2✓ Branch 0 taken 84 times.
✓ Branch 1 taken 16 times.
|
100 | if (sps->r->sps_gpm_enabled_flag) { |
151 | 84 | sps->max_num_gpm_merge_cand = 2; | |
152 |
1/2✓ Branch 0 taken 84 times.
✗ Branch 1 not taken.
|
84 | if (sps->max_num_merge_cand >= 3) |
153 | 84 | sps->max_num_gpm_merge_cand = sps->max_num_merge_cand - r->sps_max_num_merge_cand_minus_max_num_gpm_cand; | |
154 | } | ||
155 | |||
156 | 100 | sps->log2_parallel_merge_level = r->sps_log2_parallel_merge_level_minus2 + 2; | |
157 | 100 | } | |
158 | |||
159 | 100 | static void sps_partition_constraints(VVCSPS* sps) | |
160 | { | ||
161 | 100 | const H266RawSPS *r = sps->r; | |
162 | |||
163 | 100 | sps->ctb_log2_size_y = r->sps_log2_ctu_size_minus5 + 5; | |
164 | 100 | sps->ctb_size_y = 1 << sps->ctb_log2_size_y; | |
165 | 100 | sps->min_cb_log2_size_y = r->sps_log2_min_luma_coding_block_size_minus2 + 2; | |
166 | 100 | sps->min_cb_size_y = 1 << sps->min_cb_log2_size_y; | |
167 |
2/2✓ Branch 0 taken 93 times.
✓ Branch 1 taken 7 times.
|
100 | sps->max_tb_size_y = 1 << (r->sps_max_luma_transform_size_64_flag ? 6 : 5); |
168 | 100 | sps->max_ts_size = 1 << (r->sps_log2_transform_skip_max_size_minus2 + 2); | |
169 | 100 | } | |
170 | |||
171 | 100 | static void sps_ladf(VVCSPS* sps) | |
172 | { | ||
173 | 100 | const H266RawSPS *r = sps->r; | |
174 | |||
175 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 98 times.
|
100 | if (r->sps_ladf_enabled_flag) { |
176 | 2 | sps->num_ladf_intervals = r->sps_num_ladf_intervals_minus2 + 2; | |
177 | 2 | sps->ladf_interval_lower_bound[0] = 0; | |
178 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2 times.
|
6 | for (int i = 0; i < sps->num_ladf_intervals - 1; i++) { |
179 | 4 | sps->ladf_interval_lower_bound[i + 1] = | |
180 | 4 | sps->ladf_interval_lower_bound[i] + r->sps_ladf_delta_threshold_minus1[i] + 1; | |
181 | } | ||
182 | } | ||
183 | 100 | } | |
184 | |||
185 | #define EXTENDED_SAR 255 | ||
186 | 9 | static void sps_vui(AVCodecContext *c, const H266RawVUI *vui) | |
187 | { | ||
188 | 9 | AVRational sar = (AVRational){ 0, 1 }; | |
189 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 7 times.
|
9 | if (vui->vui_aspect_ratio_info_present_flag) { |
190 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
2 | if (vui->vui_aspect_ratio_idc < FF_ARRAY_ELEMS(ff_h2645_pixel_aspect)) |
191 | 2 | sar = ff_h2645_pixel_aspect[vui->vui_aspect_ratio_idc]; | |
192 | ✗ | else if (vui->vui_aspect_ratio_idc == EXTENDED_SAR) { | |
193 | ✗ | sar = (AVRational){ vui->vui_sar_width, vui->vui_sar_height }; | |
194 | } else { | ||
195 | ✗ | av_log(c, AV_LOG_WARNING, "Unknown SAR index: %u.\n", vui->vui_aspect_ratio_idc); | |
196 | } | ||
197 | } | ||
198 | 9 | ff_set_sar(c, sar); | |
199 | |||
200 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 7 times.
|
9 | if (vui->vui_colour_description_present_flag) { |
201 | 2 | c->color_primaries = vui->vui_colour_primaries; | |
202 | 2 | c->color_trc = vui->vui_transfer_characteristics; | |
203 | 2 | c->colorspace = vui->vui_matrix_coeffs; | |
204 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
2 | c->color_range = vui->vui_full_range_flag ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG; |
205 | |||
206 | // Set invalid values to "unspecified" | ||
207 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
|
2 | if (!av_color_primaries_name(c->color_primaries)) |
208 | ✗ | c->color_primaries = AVCOL_PRI_UNSPECIFIED; | |
209 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
|
2 | if (!av_color_transfer_name(c->color_trc)) |
210 | ✗ | c->color_trc = AVCOL_TRC_UNSPECIFIED; | |
211 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
|
2 | if (!av_color_space_name(c->colorspace)) |
212 | ✗ | c->colorspace = AVCOL_SPC_UNSPECIFIED; | |
213 | } else { | ||
214 | 7 | c->color_primaries = AVCOL_PRI_UNSPECIFIED; | |
215 | 7 | c->color_trc = AVCOL_TRC_UNSPECIFIED; | |
216 | 7 | c->colorspace = AVCOL_SPC_UNSPECIFIED; | |
217 | 7 | c->color_range = AVCOL_RANGE_MPEG; | |
218 | } | ||
219 | 9 | } | |
220 | |||
221 | |||
222 | 100 | static void sps_export_stream_params(AVCodecContext *c, const VVCSPS *sps) | |
223 | { | ||
224 | 100 | const H266RawSPS *r = sps->r; | |
225 | |||
226 | 100 | c->has_b_frames = !!r->sps_dpb_params.dpb_max_num_reorder_pics[r->sps_max_sublayers_minus1]; | |
227 |
2/2✓ Branch 0 taken 9 times.
✓ Branch 1 taken 91 times.
|
100 | if (r->sps_vui_parameters_present_flag) |
228 | 9 | sps_vui(c, &r->vui); | |
229 | 100 | } | |
230 | |||
231 | 100 | static int sps_derive(VVCSPS *sps, AVCodecContext *c) | |
232 | { | ||
233 | int ret; | ||
234 | 100 | const H266RawSPS *r = sps->r; | |
235 | |||
236 | 100 | ret = sps_bit_depth(sps, c); | |
237 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 100 times.
|
100 | if (ret < 0) |
238 | ✗ | return ret; | |
239 | 100 | sps_poc(sps); | |
240 | 100 | sps_inter(sps); | |
241 | 100 | sps_partition_constraints(sps); | |
242 | 100 | sps_ladf(sps); | |
243 |
2/2✓ Branch 0 taken 97 times.
✓ Branch 1 taken 3 times.
|
100 | if (r->sps_chroma_format_idc != 0) { |
244 | 97 | ret = sps_chroma_qp_table(sps); | |
245 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 97 times.
|
97 | if (ret < 0) |
246 | ✗ | return ret; | |
247 | } | ||
248 | 100 | sps_export_stream_params(c, sps); | |
249 | |||
250 | 100 | return 0; | |
251 | } | ||
252 | |||
253 | 100 | static void sps_free(AVRefStructOpaque opaque, void *obj) | |
254 | { | ||
255 | 100 | VVCSPS *sps = obj; | |
256 | 100 | av_refstruct_unref(&sps->r); | |
257 | 100 | } | |
258 | |||
259 | 100 | static const VVCSPS *sps_alloc(const H266RawSPS *rsps, AVCodecContext *c) | |
260 | { | ||
261 | int ret; | ||
262 | 100 | VVCSPS *sps = av_refstruct_alloc_ext(sizeof(*sps), 0, NULL, sps_free); | |
263 | |||
264 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 100 times.
|
100 | if (!sps) |
265 | ✗ | return NULL; | |
266 | |||
267 | 100 | av_refstruct_replace(&sps->r, rsps); | |
268 | |||
269 | 100 | ret = sps_derive(sps, c); | |
270 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 100 times.
|
100 | if (ret < 0) |
271 | ✗ | goto fail; | |
272 | |||
273 | 100 | return sps; | |
274 | |||
275 | ✗ | fail: | |
276 | ✗ | av_refstruct_unref(&sps); | |
277 | ✗ | return NULL; | |
278 | } | ||
279 | |||
280 | 1066 | static int decode_sps(VVCParamSets *ps, AVCodecContext *c, const H266RawSPS *rsps, int is_clvss) | |
281 | { | ||
282 | 1066 | const int sps_id = rsps->sps_seq_parameter_set_id; | |
283 | 1066 | const VVCSPS *old_sps = ps->sps_list[sps_id]; | |
284 | const VVCSPS *sps; | ||
285 | |||
286 |
2/2✓ Branch 0 taken 109 times.
✓ Branch 1 taken 957 times.
|
1066 | if (is_clvss) { |
287 | 109 | ps->sps_id_used = 0; | |
288 | } | ||
289 | |||
290 |
2/2✓ Branch 0 taken 971 times.
✓ Branch 1 taken 95 times.
|
1066 | if (old_sps) { |
291 |
4/4✓ Branch 0 taken 302 times.
✓ Branch 1 taken 669 times.
✓ Branch 2 taken 297 times.
✓ Branch 3 taken 5 times.
|
971 | if (old_sps->r == rsps || !memcmp(old_sps->r, rsps, sizeof(*old_sps->r))) { |
292 | 966 | ps->sps_id_used |= (1 << sps_id); | |
293 | 966 | return 0; | |
294 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
|
5 | } else if (ps->sps_id_used & (1 << sps_id)) |
295 | ✗ | return AVERROR_INVALIDDATA; | |
296 | } | ||
297 | |||
298 | 100 | sps = sps_alloc(rsps, c); | |
299 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 100 times.
|
100 | if (!sps) |
300 | ✗ | return AVERROR(ENOMEM); | |
301 | |||
302 | 100 | av_refstruct_unref(&ps->sps_list[sps_id]); | |
303 | 100 | ps->sps_list[sps_id] = sps; | |
304 | 100 | ps->sps_id_used |= (1 << sps_id); | |
305 | |||
306 | 100 | return 0; | |
307 | } | ||
308 | |||
309 | 199 | static void pps_chroma_qp_offset(VVCPPS *pps) | |
310 | { | ||
311 | 199 | pps->chroma_qp_offset[CB - 1] = pps->r->pps_cb_qp_offset; | |
312 | 199 | pps->chroma_qp_offset[CR - 1] = pps->r->pps_cr_qp_offset; | |
313 | 199 | pps->chroma_qp_offset[JCBCR - 1]= pps->r->pps_joint_cbcr_qp_offset_value; | |
314 |
2/2✓ Branch 0 taken 1194 times.
✓ Branch 1 taken 199 times.
|
1393 | for (int i = 0; i < 6; i++) { |
315 | 1194 | pps->chroma_qp_offset_list[i][CB - 1] = pps->r->pps_cb_qp_offset_list[i]; | |
316 | 1194 | pps->chroma_qp_offset_list[i][CR - 1] = pps->r->pps_cr_qp_offset_list[i]; | |
317 | 1194 | pps->chroma_qp_offset_list[i][JCBCR - 1]= pps->r->pps_joint_cbcr_qp_offset_list[i]; | |
318 | } | ||
319 | 199 | } | |
320 | |||
321 | 199 | static void pps_width_height(VVCPPS *pps, const VVCSPS *sps) | |
322 | { | ||
323 | 199 | const H266RawPPS *r = pps->r; | |
324 | |||
325 | 199 | pps->width = r->pps_pic_width_in_luma_samples; | |
326 | 199 | pps->height = r->pps_pic_height_in_luma_samples; | |
327 | |||
328 | 199 | pps->ctb_width = AV_CEIL_RSHIFT(pps->width, sps->ctb_log2_size_y); | |
329 | 199 | pps->ctb_height = AV_CEIL_RSHIFT(pps->height, sps->ctb_log2_size_y); | |
330 | 199 | pps->ctb_count = pps->ctb_width * pps->ctb_height; | |
331 | |||
332 | 199 | pps->min_cb_width = pps->width >> sps->min_cb_log2_size_y; | |
333 | 199 | pps->min_cb_height = pps->height >> sps->min_cb_log2_size_y; | |
334 | |||
335 | 199 | pps->min_pu_width = pps->width >> MIN_PU_LOG2; | |
336 | 199 | pps->min_pu_height = pps->height >> MIN_PU_LOG2; | |
337 | 199 | pps->min_tu_width = pps->width >> MIN_TU_LOG2; | |
338 | 199 | pps->min_tu_height = pps->height >> MIN_TU_LOG2; | |
339 | |||
340 | 199 | pps->width32 = AV_CEIL_RSHIFT(pps->width, 5); | |
341 | 199 | pps->height32 = AV_CEIL_RSHIFT(pps->height, 5); | |
342 | 199 | pps->width64 = AV_CEIL_RSHIFT(pps->width, 6); | |
343 | 199 | pps->height64 = AV_CEIL_RSHIFT(pps->height, 6); | |
344 | 199 | } | |
345 | |||
346 | 199 | static int pps_bd(VVCPPS *pps) | |
347 | { | ||
348 | 199 | const H266RawPPS *r = pps->r; | |
349 | |||
350 | 199 | pps->col_bd = av_calloc(r->num_tile_columns + 1, sizeof(*pps->col_bd)); | |
351 | 199 | pps->row_bd = av_calloc(r->num_tile_rows + 1, sizeof(*pps->row_bd)); | |
352 | 199 | pps->ctb_to_col_bd = av_calloc(pps->ctb_width + 1, sizeof(*pps->ctb_to_col_bd)); | |
353 | 199 | pps->ctb_to_row_bd = av_calloc(pps->ctb_height + 1, sizeof(*pps->ctb_to_col_bd)); | |
354 |
4/8✓ Branch 0 taken 199 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 199 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 199 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 199 times.
|
199 | if (!pps->col_bd || !pps->row_bd || !pps->ctb_to_col_bd || !pps->ctb_to_row_bd) |
355 | ✗ | return AVERROR(ENOMEM); | |
356 | |||
357 |
2/2✓ Branch 0 taken 312 times.
✓ Branch 1 taken 199 times.
|
511 | for (int i = 0, j = 0; i < r->num_tile_columns; i++) { |
358 | 312 | pps->col_bd[i] = j; | |
359 | 312 | j += r->col_width_val[i]; | |
360 |
2/2✓ Branch 0 taken 1359 times.
✓ Branch 1 taken 312 times.
|
1671 | for (int k = pps->col_bd[i]; k < j; k++) |
361 | 1359 | pps->ctb_to_col_bd[k] = pps->col_bd[i]; | |
362 | } | ||
363 | 199 | pps->col_bd[r->num_tile_columns] = pps->ctb_to_col_bd[pps->ctb_width] = pps->ctb_width; | |
364 | |||
365 |
2/2✓ Branch 0 taken 302 times.
✓ Branch 1 taken 199 times.
|
501 | for (int i = 0, j = 0; i < r->num_tile_rows; i++) { |
366 | 302 | pps->row_bd[i] = j; | |
367 | 302 | j += r->row_height_val[i]; | |
368 |
2/2✓ Branch 0 taken 825 times.
✓ Branch 1 taken 302 times.
|
1127 | for (int k = pps->row_bd[i]; k < j; k++) |
369 | 825 | pps->ctb_to_row_bd[k] = pps->row_bd[i]; | |
370 | } | ||
371 | 199 | pps->row_bd[r->num_tile_rows] = pps->ctb_to_row_bd[pps->ctb_height] = pps->ctb_height; | |
372 | |||
373 | 199 | return 0; | |
374 | } | ||
375 | |||
376 | |||
377 | 158 | static int next_tile_idx(int tile_idx, const int i, const H266RawPPS *r) | |
378 | { | ||
379 |
2/2✓ Branch 0 taken 61 times.
✓ Branch 1 taken 97 times.
|
158 | if (r->pps_tile_idx_delta_present_flag) { |
380 | 61 | tile_idx += r->pps_tile_idx_delta_val[i]; | |
381 | } else { | ||
382 | 97 | tile_idx += r->pps_slice_width_in_tiles_minus1[i] + 1; | |
383 |
2/2✓ Branch 0 taken 52 times.
✓ Branch 1 taken 45 times.
|
97 | if (tile_idx % r->num_tile_columns == 0) |
384 | 52 | tile_idx += (r->pps_slice_height_in_tiles_minus1[i]) * r->num_tile_columns; | |
385 | } | ||
386 | 158 | return tile_idx; | |
387 | } | ||
388 | |||
389 | 158 | static void tile_xy(int *tile_x, int *tile_y, const int tile_idx, const VVCPPS *pps) | |
390 | { | ||
391 | 158 | *tile_x = tile_idx % pps->r->num_tile_columns; | |
392 | 158 | *tile_y = tile_idx / pps->r->num_tile_columns; | |
393 | 158 | } | |
394 | |||
395 | 720 | static void ctu_xy(int *rx, int *ry, const int tile_x, const int tile_y, const VVCPPS *pps) | |
396 | { | ||
397 | 720 | *rx = pps->col_bd[tile_x]; | |
398 | 720 | *ry = pps->row_bd[tile_y]; | |
399 | 720 | } | |
400 | |||
401 | 7893 | static int ctu_rs(const int rx, const int ry, const VVCPPS *pps) | |
402 | { | ||
403 | 7893 | return pps->ctb_width * ry + rx; | |
404 | } | ||
405 | |||
406 | 776 | static int pps_add_ctus(VVCPPS *pps, int *off, const int rx, const int ry, | |
407 | const int w, const int h) | ||
408 | { | ||
409 | 776 | int start = *off; | |
410 |
2/2✓ Branch 0 taken 1660 times.
✓ Branch 1 taken 776 times.
|
2436 | for (int y = 0; y < h; y++) { |
411 |
2/2✓ Branch 0 taken 7893 times.
✓ Branch 1 taken 1660 times.
|
9553 | for (int x = 0; x < w; x++) { |
412 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 7893 times.
|
7893 | if (*off >= pps->ctb_count) |
413 | ✗ | return AVERROR_INVALIDDATA; | |
414 | 7893 | pps->ctb_addr_in_slice[*off] = ctu_rs(rx + x, ry + y, pps); | |
415 | 7893 | (*off)++; | |
416 | } | ||
417 | } | ||
418 | 776 | return *off - start; | |
419 | } | ||
420 | |||
421 | 2 | static int pps_single_slice_picture(VVCPPS *pps, int *off) | |
422 | { | ||
423 | 2 | pps->num_ctus_in_slice[0] = 0; | |
424 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2 times.
|
6 | for (int j = 0; j < pps->r->num_tile_rows; j++) { |
425 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 4 times.
|
12 | for (int i = 0; i < pps->r->num_tile_columns; i++) { |
426 | 8 | const int ret = pps_add_ctus(pps, off, | |
427 | 8 | pps->col_bd[i], pps->row_bd[j], | |
428 | 8 | pps->r->col_width_val[i], pps->r->row_height_val[j]); | |
429 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
|
8 | if (ret < 0) |
430 | ✗ | return ret; | |
431 | 8 | pps->num_ctus_in_slice[0] += ret; | |
432 | } | ||
433 | } | ||
434 | |||
435 | 2 | return 0; | |
436 | } | ||
437 | |||
438 | 16 | static void subpic_tiles(int *tile_x, int *tile_y, int *tile_x_end, int *tile_y_end, | |
439 | const VVCSPS *sps, const VVCPPS *pps, const int i) | ||
440 | { | ||
441 | 16 | const int rx = sps->r->sps_subpic_ctu_top_left_x[i]; | |
442 | 16 | const int ry = sps->r->sps_subpic_ctu_top_left_y[i]; | |
443 | |||
444 | 16 | *tile_x = *tile_y = 0; | |
445 | |||
446 |
2/2✓ Branch 0 taken 24 times.
✓ Branch 1 taken 16 times.
|
40 | while (pps->col_bd[*tile_x] < rx) |
447 | 24 | (*tile_x)++; | |
448 | |||
449 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 16 times.
|
24 | while (pps->row_bd[*tile_y] < ry) |
450 | 8 | (*tile_y)++; | |
451 | |||
452 | 16 | *tile_x_end = (*tile_x); | |
453 | 16 | *tile_y_end = (*tile_y); | |
454 | |||
455 |
2/2✓ Branch 0 taken 16 times.
✓ Branch 1 taken 16 times.
|
32 | while (pps->col_bd[*tile_x_end] < rx + sps->r->sps_subpic_width_minus1[i] + 1) |
456 | 16 | (*tile_x_end)++; | |
457 | |||
458 |
2/2✓ Branch 0 taken 16 times.
✓ Branch 1 taken 16 times.
|
32 | while (pps->row_bd[*tile_y_end] < ry + sps->r->sps_subpic_height_minus1[i] + 1) |
459 | 16 | (*tile_y_end)++; | |
460 | 16 | } | |
461 | |||
462 | ✗ | static int pps_subpic_less_than_one_tile_slice(VVCPPS *pps, const VVCSPS *sps, const int i, const int tx, const int ty, int *off) | |
463 | { | ||
464 | ✗ | const int ret = pps_add_ctus(pps, off, | |
465 | ✗ | sps->r->sps_subpic_ctu_top_left_x[i], sps->r->sps_subpic_ctu_top_left_y[i], | |
466 | ✗ | sps->r->sps_subpic_width_minus1[i] + 1, sps->r->sps_subpic_height_minus1[i] + 1); | |
467 | ✗ | if (ret < 0) | |
468 | ✗ | return ret; | |
469 | |||
470 | ✗ | pps->num_ctus_in_slice[i] = ret; | |
471 | ✗ | return 0; | |
472 | } | ||
473 | |||
474 | 16 | static int pps_subpic_one_or_more_tiles_slice(VVCPPS *pps, const int tile_x, const int tile_y, const int x_end, const int y_end, | |
475 | const int i, int *off) | ||
476 | { | ||
477 |
2/2✓ Branch 0 taken 16 times.
✓ Branch 1 taken 16 times.
|
32 | for (int ty = tile_y; ty < y_end; ty++) { |
478 |
2/2✓ Branch 0 taken 16 times.
✓ Branch 1 taken 16 times.
|
32 | for (int tx = tile_x; tx < x_end; tx++) { |
479 | 16 | const int ret = pps_add_ctus(pps, off, | |
480 | 16 | pps->col_bd[tx], pps->row_bd[ty], | |
481 | 16 | pps->r->col_width_val[tx], pps->r->row_height_val[ty]); | |
482 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
|
16 | if (ret < 0) |
483 | ✗ | return ret; | |
484 | |||
485 | 16 | pps->num_ctus_in_slice[i] += ret; | |
486 | } | ||
487 | } | ||
488 | 16 | return 0; | |
489 | } | ||
490 | |||
491 | 16 | static int pps_subpic_slice(VVCPPS *pps, const VVCSPS *sps, const int i, int *off) | |
492 | { | ||
493 | int tx, ty, x_end, y_end; | ||
494 | |||
495 | 16 | pps->slice_start_offset[i] = *off; | |
496 | 16 | pps->num_ctus_in_slice[i] = 0; | |
497 | |||
498 | 16 | subpic_tiles(&tx, &ty, &x_end, &y_end, sps, pps, i); | |
499 |
2/4✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 16 times.
|
16 | if (ty + 1 == y_end && sps->r->sps_subpic_height_minus1[i] + 1 < pps->r->row_height_val[ty]) |
500 | ✗ | return pps_subpic_less_than_one_tile_slice(pps, sps, i, tx, ty, off); | |
501 | else | ||
502 | 16 | return pps_subpic_one_or_more_tiles_slice(pps, tx, ty, x_end, y_end, i, off); | |
503 | } | ||
504 | |||
505 | 4 | static int pps_single_slice_per_subpic(VVCPPS *pps, const VVCSPS *sps, int *off) | |
506 | { | ||
507 | int ret; | ||
508 | |||
509 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
|
4 | if (!sps->r->sps_subpic_info_present_flag) { |
510 | 2 | ret = pps_single_slice_picture(pps, off); | |
511 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
2 | if (ret < 0) |
512 | ✗ | return ret; | |
513 | } else { | ||
514 |
2/2✓ Branch 0 taken 16 times.
✓ Branch 1 taken 2 times.
|
18 | for (int i = 0; i < pps->r->pps_num_slices_in_pic_minus1 + 1; i++) { |
515 | 16 | const int ret = pps_subpic_slice(pps, sps, i, off); | |
516 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
|
16 | if (ret < 0) |
517 | ✗ | return ret; | |
518 | } | ||
519 | } | ||
520 | 4 | return 0; | |
521 | } | ||
522 | |||
523 | 95 | static int pps_one_tile_slices(VVCPPS *pps, const int tile_idx, int i, int *off) | |
524 | { | ||
525 | 95 | const H266RawPPS *r = pps->r; | |
526 | int rx, ry, ctu_y_end, tile_x, tile_y; | ||
527 | |||
528 | 95 | tile_xy(&tile_x, &tile_y, tile_idx, pps); | |
529 | 95 | ctu_xy(&rx, &ry, tile_x, tile_y, pps); | |
530 | 95 | ctu_y_end = ry + r->row_height_val[tile_y]; | |
531 |
2/2✓ Branch 0 taken 127 times.
✓ Branch 1 taken 95 times.
|
222 | while (ry < ctu_y_end) { |
532 | int ret; | ||
533 | 127 | pps->slice_start_offset[i] = *off; | |
534 | 127 | ret = pps_add_ctus(pps, off, rx, ry, | |
535 | 127 | r->col_width_val[tile_x], r->slice_height_in_ctus[i]); | |
536 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 127 times.
|
127 | if (ret < 0) |
537 | ✗ | return ret; | |
538 | 127 | pps->num_ctus_in_slice[i] = ret; | |
539 | 127 | ry += r->slice_height_in_ctus[i++]; | |
540 | } | ||
541 | 95 | i--; | |
542 | 95 | return i; | |
543 | } | ||
544 | |||
545 | 63 | static int pps_multi_tiles_slice(VVCPPS *pps, const int tile_idx, const int i, int *off, bool *tile_in_slice) | |
546 | { | ||
547 | 63 | const H266RawPPS *r = pps->r; | |
548 | int rx, ry, tile_x, tile_y; | ||
549 | |||
550 | 63 | tile_xy(&tile_x, &tile_y, tile_idx, pps); | |
551 | 63 | pps->slice_start_offset[i] = *off; | |
552 | 63 | pps->num_ctus_in_slice[i] = 0; | |
553 |
2/2✓ Branch 0 taken 123 times.
✓ Branch 1 taken 63 times.
|
186 | for (int ty = tile_y; ty <= tile_y + r->pps_slice_height_in_tiles_minus1[i]; ty++) { |
554 |
2/2✓ Branch 0 taken 414 times.
✓ Branch 1 taken 123 times.
|
537 | for (int tx = tile_x; tx <= tile_x + r->pps_slice_width_in_tiles_minus1[i]; tx++) { |
555 | int ret; | ||
556 | 414 | const int idx = ty * r->num_tile_columns + tx; | |
557 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 414 times.
|
414 | if (tile_in_slice[idx]) |
558 | ✗ | return AVERROR_INVALIDDATA; | |
559 | 414 | tile_in_slice[idx] = true; | |
560 | 414 | ctu_xy(&rx, &ry, tx, ty, pps); | |
561 | 414 | ret = pps_add_ctus(pps, off, rx, ry, | |
562 | 414 | r->col_width_val[tx], r->row_height_val[ty]); | |
563 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 414 times.
|
414 | if (ret < 0) |
564 | ✗ | return ret; | |
565 | 414 | pps->num_ctus_in_slice[i] += ret; | |
566 | } | ||
567 | } | ||
568 | |||
569 | 63 | return 0; | |
570 | } | ||
571 | |||
572 | 36 | static int pps_rect_slice(VVCPPS *pps, const VVCSPS *sps) | |
573 | { | ||
574 | 36 | const H266RawPPS *r = pps->r; | |
575 | 36 | bool tile_in_slice[VVC_MAX_TILES_PER_AU] = {false}; | |
576 | 36 | int tile_idx = 0, off = 0, ret; | |
577 | |||
578 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 32 times.
|
36 | if (r->pps_single_slice_per_subpic_flag) { |
579 | 4 | return pps_single_slice_per_subpic(pps, sps, &off); | |
580 | } | ||
581 | |||
582 |
2/2✓ Branch 0 taken 158 times.
✓ Branch 1 taken 32 times.
|
190 | for (int i = 0; i < r->pps_num_slices_in_pic_minus1 + 1; i++) { |
583 |
2/2✓ Branch 0 taken 101 times.
✓ Branch 1 taken 57 times.
|
158 | if (!r->pps_slice_width_in_tiles_minus1[i] && |
584 |
2/2✓ Branch 0 taken 95 times.
✓ Branch 1 taken 6 times.
|
101 | !r->pps_slice_height_in_tiles_minus1[i]) { |
585 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 95 times.
|
95 | if (tile_in_slice[tile_idx]) |
586 | ✗ | return AVERROR_INVALIDDATA; | |
587 | 95 | tile_in_slice[tile_idx] = true; | |
588 | 95 | ret = pps_one_tile_slices(pps, tile_idx, i, &off); | |
589 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 95 times.
|
95 | if (ret < 0) |
590 | ✗ | return ret; | |
591 | 95 | i = ret; | |
592 | } else { | ||
593 | 63 | ret = pps_multi_tiles_slice(pps, tile_idx, i, &off, tile_in_slice); | |
594 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 63 times.
|
63 | if (ret < 0) |
595 | ✗ | return ret; | |
596 | } | ||
597 | 158 | tile_idx = next_tile_idx(tile_idx, i, r); | |
598 | } | ||
599 | |||
600 |
2/2✓ Branch 0 taken 509 times.
✓ Branch 1 taken 32 times.
|
541 | for (int i = 0; i < r->num_tiles_in_pic; i++) { |
601 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 509 times.
|
509 | if (!tile_in_slice[i]) |
602 | ✗ | return AVERROR_INVALIDDATA; | |
603 | } | ||
604 | |||
605 | 32 | return 0; | |
606 | } | ||
607 | |||
608 | 163 | static int pps_no_rect_slice(VVCPPS* pps) | |
609 | { | ||
610 | 163 | const H266RawPPS* r = pps->r; | |
611 | 163 | int rx, ry, off = 0; | |
612 | |||
613 |
2/2✓ Branch 0 taken 171 times.
✓ Branch 1 taken 163 times.
|
334 | for (int tile_y = 0; tile_y < r->num_tile_rows; tile_y++) { |
614 |
2/2✓ Branch 0 taken 211 times.
✓ Branch 1 taken 171 times.
|
382 | for (int tile_x = 0; tile_x < r->num_tile_columns; tile_x++) { |
615 | int ret; | ||
616 | 211 | ctu_xy(&rx, &ry, tile_x, tile_y, pps); | |
617 | 211 | ret = pps_add_ctus(pps, &off, rx, ry, r->col_width_val[tile_x], r->row_height_val[tile_y]); | |
618 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 211 times.
|
211 | if (ret < 0) |
619 | ✗ | return ret; | |
620 | } | ||
621 | } | ||
622 | |||
623 | 163 | return 0; | |
624 | } | ||
625 | |||
626 | 199 | static int pps_slice_map(VVCPPS *pps, const VVCSPS *sps) | |
627 | { | ||
628 | int ret; | ||
629 | |||
630 | 199 | pps->ctb_addr_in_slice = av_calloc(pps->ctb_count, sizeof(*pps->ctb_addr_in_slice)); | |
631 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 199 times.
|
199 | if (!pps->ctb_addr_in_slice) |
632 | ✗ | return AVERROR(ENOMEM); | |
633 | |||
634 |
2/2✓ Branch 0 taken 36 times.
✓ Branch 1 taken 163 times.
|
199 | if (pps->r->pps_rect_slice_flag) |
635 | 36 | return pps_rect_slice(pps, sps); | |
636 | |||
637 | 163 | ret = pps_no_rect_slice(pps); | |
638 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 163 times.
|
163 | if (ret < 0) |
639 | ✗ | return ret; | |
640 | |||
641 | 163 | return 0; | |
642 | } | ||
643 | |||
644 | 199 | static void pps_ref_wraparound_offset(VVCPPS *pps, const VVCSPS *sps) | |
645 | { | ||
646 | 199 | const H266RawPPS *r = pps->r; | |
647 | |||
648 |
2/2✓ Branch 0 taken 3 times.
✓ Branch 1 taken 196 times.
|
199 | if (r->pps_ref_wraparound_enabled_flag) |
649 | 3 | pps->ref_wraparound_offset = (pps->width / sps->min_cb_size_y) - r->pps_pic_width_minus_wraparound_offset; | |
650 | 199 | } | |
651 | |||
652 | 199 | static void pps_subpic(VVCPPS *pps, const VVCSPS *sps) | |
653 | { | ||
654 | 199 | const H266RawSPS *rsps = sps->r; | |
655 |
2/2✓ Branch 0 taken 279 times.
✓ Branch 1 taken 199 times.
|
478 | for (int i = 0; i < rsps->sps_num_subpics_minus1 + 1; i++) { |
656 |
2/2✓ Branch 0 taken 109 times.
✓ Branch 1 taken 170 times.
|
279 | if (rsps->sps_subpic_treated_as_pic_flag[i]) { |
657 | 109 | pps->subpic_x[i] = rsps->sps_subpic_ctu_top_left_x[i] << sps->ctb_log2_size_y; | |
658 | 109 | pps->subpic_y[i] = rsps->sps_subpic_ctu_top_left_y[i] << sps->ctb_log2_size_y; | |
659 | 109 | pps->subpic_width[i] = FFMIN(pps->width - pps->subpic_x[i], (rsps->sps_subpic_width_minus1[i] + 1) << sps->ctb_log2_size_y); | |
660 | 109 | pps->subpic_height[i] = FFMIN(pps->height - pps->subpic_y[i], (rsps->sps_subpic_height_minus1[i] + 1) << sps->ctb_log2_size_y); | |
661 | } else { | ||
662 | 170 | pps->subpic_x[i] = 0; | |
663 | 170 | pps->subpic_y[i] = 0; | |
664 | 170 | pps->subpic_width[i] = pps->width; | |
665 | 170 | pps->subpic_height[i] = pps->height; | |
666 | } | ||
667 | } | ||
668 | 199 | } | |
669 | |||
670 | 199 | static int pps_derive(VVCPPS *pps, const VVCSPS *sps) | |
671 | { | ||
672 | int ret; | ||
673 | |||
674 | 199 | pps_chroma_qp_offset(pps); | |
675 | 199 | pps_width_height(pps, sps); | |
676 | |||
677 | 199 | ret = pps_bd(pps); | |
678 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 199 times.
|
199 | if (ret < 0) |
679 | ✗ | return ret; | |
680 | |||
681 | 199 | ret = pps_slice_map(pps, sps); | |
682 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 199 times.
|
199 | if (ret < 0) |
683 | ✗ | return ret; | |
684 | |||
685 | 199 | pps_ref_wraparound_offset(pps, sps); | |
686 | 199 | pps_subpic(pps, sps); | |
687 | |||
688 | 199 | return 0; | |
689 | } | ||
690 | |||
691 | 199 | static void pps_free(AVRefStructOpaque opaque, void *obj) | |
692 | { | ||
693 | 199 | VVCPPS *pps = obj; | |
694 | |||
695 | 199 | av_refstruct_unref(&pps->r); | |
696 | |||
697 | 199 | av_freep(&pps->col_bd); | |
698 | 199 | av_freep(&pps->row_bd); | |
699 | 199 | av_freep(&pps->ctb_to_col_bd); | |
700 | 199 | av_freep(&pps->ctb_to_row_bd); | |
701 | 199 | av_freep(&pps->ctb_addr_in_slice); | |
702 | 199 | } | |
703 | |||
704 | 199 | static const VVCPPS *pps_alloc(const H266RawPPS *rpps, const VVCSPS *sps) | |
705 | { | ||
706 | int ret; | ||
707 | 199 | VVCPPS *pps = av_refstruct_alloc_ext(sizeof(*pps), 0, NULL, pps_free); | |
708 | |||
709 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 199 times.
|
199 | if (!pps) |
710 | ✗ | return NULL; | |
711 | |||
712 | 199 | av_refstruct_replace(&pps->r, rpps); | |
713 | |||
714 | 199 | ret = pps_derive(pps, sps); | |
715 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 199 times.
|
199 | if (ret < 0) |
716 | ✗ | goto fail; | |
717 | |||
718 | 199 | return pps; | |
719 | |||
720 | ✗ | fail: | |
721 | ✗ | av_refstruct_unref(&pps); | |
722 | ✗ | return NULL; | |
723 | } | ||
724 | |||
725 | 1066 | static int decode_pps(VVCParamSets *ps, const H266RawPPS *rpps) | |
726 | { | ||
727 | 1066 | int ret = 0; | |
728 | 1066 | const int pps_id = rpps->pps_pic_parameter_set_id; | |
729 | 1066 | const int sps_id = rpps->pps_seq_parameter_set_id; | |
730 | 1066 | const VVCPPS *old_pps = ps->pps_list[pps_id]; | |
731 | const VVCPPS *pps; | ||
732 | |||
733 |
4/4✓ Branch 0 taken 949 times.
✓ Branch 1 taken 117 times.
✓ Branch 2 taken 867 times.
✓ Branch 3 taken 82 times.
|
1066 | if (old_pps && old_pps->r == rpps) |
734 | 867 | return 0; | |
735 | |||
736 | 199 | pps = pps_alloc(rpps, ps->sps_list[sps_id]); | |
737 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 199 times.
|
199 | if (!pps) |
738 | ✗ | return AVERROR(ENOMEM); | |
739 | |||
740 | 199 | av_refstruct_unref(&ps->pps_list[pps_id]); | |
741 | 199 | ps->pps_list[pps_id] = pps; | |
742 | |||
743 | 199 | return ret; | |
744 | } | ||
745 | |||
746 | 1066 | static int decode_ps(VVCParamSets *ps, AVCodecContext *c, const SliceContext *sc, int is_clvss) | |
747 | { | ||
748 | 1066 | const H266RawSlice *sl = sc->ref; | |
749 | 1066 | const H266RawPPS *rpps = sl->pps; | |
750 | 1066 | const H266RawSPS *rsps = sl->sps; | |
751 | int ret; | ||
752 | |||
753 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1066 times.
|
1066 | if (!rpps) |
754 | ✗ | return AVERROR_INVALIDDATA; | |
755 | |||
756 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1066 times.
|
1066 | if (!rsps) |
757 | ✗ | return AVERROR_INVALIDDATA; | |
758 | |||
759 | 1066 | ret = decode_sps(ps, c, rsps, is_clvss); | |
760 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1066 times.
|
1066 | if (ret < 0) |
761 | ✗ | return ret; | |
762 | |||
763 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1066 times.
|
1066 | if (rsps->sps_log2_ctu_size_minus5 > 2) { |
764 | // CTU > 128 are reserved in vvc spec v3 | ||
765 | ✗ | av_log(c, AV_LOG_ERROR, "CTU size > 128. \n"); | |
766 | ✗ | return AVERROR_PATCHWELCOME; | |
767 | } | ||
768 | |||
769 | 1066 | ret = decode_pps(ps, rpps); | |
770 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1066 times.
|
1066 | if (ret < 0) |
771 | ✗ | return ret; | |
772 | |||
773 | 1066 | return 0; | |
774 | } | ||
775 | |||
776 | #define WEIGHT_TABLE(x) \ | ||
777 | w->nb_weights[L##x] = r->num_weights_l##x; \ | ||
778 | for (int i = 0; i < w->nb_weights[L##x]; i++) { \ | ||
779 | w->weight_flag[L##x][LUMA][i] = r->luma_weight_l##x##_flag[i]; \ | ||
780 | w->weight_flag[L##x][CHROMA][i] = r->chroma_weight_l##x##_flag[i]; \ | ||
781 | w->weight[L##x][LUMA][i] = denom[LUMA] + r->delta_luma_weight_l##x[i]; \ | ||
782 | w->offset[L##x][LUMA][i] = r->luma_offset_l##x[i]; \ | ||
783 | for (int j = CB; j <= CR; j++) { \ | ||
784 | w->weight[L##x][j][i] = denom[CHROMA] + r->delta_chroma_weight_l##x[i][j - 1]; \ | ||
785 | w->offset[L##x][j][i] = 128 + r->delta_chroma_offset_l##x[i][j - 1]; \ | ||
786 | w->offset[L##x][j][i] -= (128 * w->weight[L##x][j][i]) >> w->log2_denom[CHROMA]; \ | ||
787 | w->offset[L##x][j][i] = av_clip_intp2(w->offset[L##x][j][i], 7); \ | ||
788 | } \ | ||
789 | } \ | ||
790 | |||
791 | 73 | static void pred_weight_table(PredWeightTable *w, const H266RawPredWeightTable *r) | |
792 | { | ||
793 | int denom[2]; | ||
794 | |||
795 | 73 | w->log2_denom[LUMA] = r->luma_log2_weight_denom; | |
796 | 73 | w->log2_denom[CHROMA] = w->log2_denom[LUMA] + r->delta_chroma_log2_weight_denom; | |
797 | 73 | denom[LUMA] = 1 << w->log2_denom[LUMA]; | |
798 | 73 | denom[CHROMA] = 1 << w->log2_denom[CHROMA]; | |
799 |
4/4✓ Branch 0 taken 830 times.
✓ Branch 1 taken 415 times.
✓ Branch 2 taken 415 times.
✓ Branch 3 taken 73 times.
|
1318 | WEIGHT_TABLE(0) |
800 |
4/4✓ Branch 0 taken 710 times.
✓ Branch 1 taken 355 times.
✓ Branch 2 taken 355 times.
✓ Branch 3 taken 73 times.
|
1138 | WEIGHT_TABLE(1) |
801 | 73 | } | |
802 | |||
803 | // 8.3.1 Decoding process for picture order count | ||
804 | 1066 | static int ph_compute_poc(const H266RawPictureHeader *ph, const H266RawSPS *sps, const int poc_tid0, const int is_clvss) | |
805 | { | ||
806 | 1066 | const int max_poc_lsb = 1 << (sps->sps_log2_max_pic_order_cnt_lsb_minus4 + 4); | |
807 | 1066 | const int prev_poc_lsb = poc_tid0 % max_poc_lsb; | |
808 | 1066 | const int prev_poc_msb = poc_tid0 - prev_poc_lsb; | |
809 | 1066 | const int poc_lsb = ph->ph_pic_order_cnt_lsb; | |
810 | int poc_msb; | ||
811 | |||
812 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1066 times.
|
1066 | if (ph->ph_poc_msb_cycle_present_flag) { |
813 | ✗ | poc_msb = ph->ph_poc_msb_cycle_val * max_poc_lsb; | |
814 |
2/2✓ Branch 0 taken 109 times.
✓ Branch 1 taken 957 times.
|
1066 | } else if (is_clvss) { |
815 | 109 | poc_msb = 0; | |
816 | } else { | ||
817 |
3/4✓ Branch 0 taken 598 times.
✓ Branch 1 taken 359 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 598 times.
|
957 | if (poc_lsb < prev_poc_lsb && prev_poc_lsb - poc_lsb >= max_poc_lsb / 2) |
818 | ✗ | poc_msb = prev_poc_msb + max_poc_lsb; | |
819 |
3/4✓ Branch 0 taken 359 times.
✓ Branch 1 taken 598 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 359 times.
|
957 | else if (poc_lsb > prev_poc_lsb && poc_lsb - prev_poc_lsb > max_poc_lsb / 2) |
820 | ✗ | poc_msb = prev_poc_msb - max_poc_lsb; | |
821 | else | ||
822 | 957 | poc_msb = prev_poc_msb; | |
823 | } | ||
824 | |||
825 | 1066 | return poc_msb + poc_lsb; | |
826 | } | ||
827 | |||
828 | 774144 | static av_always_inline uint16_t lmcs_derive_lut_sample(uint16_t sample, | |
829 | uint16_t *pivot1, uint16_t *pivot2, uint16_t *scale_coeff, const int idx, const int max) | ||
830 | { | ||
831 | 774144 | const int lut_sample = | |
832 | 774144 | pivot1[idx] + ((scale_coeff[idx] * (sample - pivot2[idx]) + (1<< 10)) >> 11); | |
833 | 774144 | return av_clip(lut_sample, 0, max - 1); | |
834 | } | ||
835 | |||
836 | //8.8.2.2 Inverse mapping process for a luma sample | ||
837 | 378 | static int lmcs_derive_lut(VVCLMCS *lmcs, const H266RawAPS *rlmcs, const H266RawSPS *sps) | |
838 | { | ||
839 | 378 | const int bit_depth = (sps->sps_bitdepth_minus8 + 8); | |
840 | 378 | const int max = (1 << bit_depth); | |
841 | 378 | const int org_cw = max / LMCS_MAX_BIN_SIZE; | |
842 | 378 | const int shift = av_log2(org_cw); | |
843 | 378 | const int off = 1 << (shift - 1); | |
844 | int cw[LMCS_MAX_BIN_SIZE]; | ||
845 | uint16_t input_pivot[LMCS_MAX_BIN_SIZE]; | ||
846 | uint16_t scale_coeff[LMCS_MAX_BIN_SIZE]; | ||
847 | uint16_t inv_scale_coeff[LMCS_MAX_BIN_SIZE]; | ||
848 | 378 | int i, delta_crs, sum_cw = 0; | |
849 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 378 times.
|
378 | if (bit_depth > LMCS_MAX_BIT_DEPTH) |
850 | ✗ | return AVERROR_PATCHWELCOME; | |
851 | |||
852 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 378 times.
|
378 | if (!rlmcs) |
853 | ✗ | return AVERROR_INVALIDDATA; | |
854 | |||
855 | 378 | lmcs->min_bin_idx = rlmcs->lmcs_min_bin_idx; | |
856 | 378 | lmcs->max_bin_idx = LMCS_MAX_BIN_SIZE - 1 - rlmcs->lmcs_delta_max_bin_idx; | |
857 | |||
858 | 378 | memset(cw, 0, sizeof(cw)); | |
859 |
2/2✓ Branch 0 taken 5037 times.
✓ Branch 1 taken 378 times.
|
5415 | for (int i = lmcs->min_bin_idx; i <= lmcs->max_bin_idx; i++) { |
860 | 5037 | cw[i] = org_cw + (1 - 2 * rlmcs->lmcs_delta_sign_cw_flag[i]) * rlmcs->lmcs_delta_abs_cw[i]; | |
861 | 5037 | sum_cw += cw[i]; | |
862 | } | ||
863 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 378 times.
|
378 | if (sum_cw > (1 << bit_depth) - 1) |
864 | ✗ | return AVERROR_INVALIDDATA; | |
865 | |||
866 | 378 | delta_crs = (1 - 2 * rlmcs->lmcs_delta_sign_crs_flag) * rlmcs->lmcs_delta_abs_crs; | |
867 | |||
868 | 378 | lmcs->pivot[0] = 0; | |
869 |
2/2✓ Branch 0 taken 6048 times.
✓ Branch 1 taken 378 times.
|
6426 | for (i = 0; i < LMCS_MAX_BIN_SIZE; i++) { |
870 | 6048 | input_pivot[i] = i * org_cw; | |
871 | 6048 | lmcs->pivot[i + 1] = lmcs->pivot[i] + cw[i]; | |
872 |
4/4✓ Branch 0 taken 5644 times.
✓ Branch 1 taken 404 times.
✓ Branch 2 taken 5037 times.
✓ Branch 3 taken 607 times.
|
6048 | if (i >= lmcs->min_bin_idx && i <= lmcs->max_bin_idx && |
873 |
2/2✓ Branch 0 taken 4456 times.
✓ Branch 1 taken 581 times.
|
5037 | lmcs->pivot[i] % (1 << (bit_depth - 5)) != 0 && |
874 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4456 times.
|
4456 | lmcs->pivot[i] >> (bit_depth - 5) == lmcs->pivot[i + 1] >> (bit_depth - 5)) |
875 | ✗ | return AVERROR_INVALIDDATA; | |
876 | 6048 | scale_coeff[i] = (cw[i] * (1 << 11) + off) >> shift; | |
877 |
2/2✓ Branch 0 taken 1011 times.
✓ Branch 1 taken 5037 times.
|
6048 | if (cw[i] == 0) { |
878 | 1011 | inv_scale_coeff[i] = 0; | |
879 | 1011 | lmcs->chroma_scale_coeff[i] = (1 << 11); | |
880 | } else { | ||
881 | 5037 | const int cw_plus_d = cw[i] + delta_crs; | |
882 |
2/4✓ Branch 0 taken 5037 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 5037 times.
|
5037 | if (cw_plus_d < (org_cw >> 3) || cw_plus_d > ((org_cw << 3) - 1)) |
883 | ✗ | return AVERROR_INVALIDDATA; | |
884 | 5037 | inv_scale_coeff[i] = org_cw * (1 << 11) / cw[i]; | |
885 | 5037 | lmcs->chroma_scale_coeff[i] = org_cw * (1 << 11) / cw_plus_d; | |
886 | } | ||
887 | } | ||
888 | |||
889 | //derive lmcs_fwd_lut | ||
890 |
2/2✓ Branch 0 taken 387072 times.
✓ Branch 1 taken 378 times.
|
387450 | for (uint16_t sample = 0; sample < max; sample++) { |
891 | 387072 | const int idx_y = sample >> shift; | |
892 | 387072 | const uint16_t fwd_sample = lmcs_derive_lut_sample(sample, lmcs->pivot, | |
893 | input_pivot, scale_coeff, idx_y, max); | ||
894 |
1/2✓ Branch 0 taken 387072 times.
✗ Branch 1 not taken.
|
387072 | if (bit_depth > 8) |
895 | 387072 | lmcs->fwd_lut.u16[sample] = fwd_sample; | |
896 | else | ||
897 | ✗ | lmcs->fwd_lut.u8 [sample] = fwd_sample; | |
898 | |||
899 | } | ||
900 | |||
901 | //derive lmcs_inv_lut | ||
902 | 378 | i = lmcs->min_bin_idx; | |
903 |
2/2✓ Branch 0 taken 387072 times.
✓ Branch 1 taken 378 times.
|
387450 | for (uint16_t sample = 0; sample < max; sample++) { |
904 | uint16_t inv_sample; | ||
905 |
4/4✓ Branch 0 taken 375898 times.
✓ Branch 1 taken 16211 times.
✓ Branch 2 taken 5037 times.
✓ Branch 3 taken 370861 times.
|
392109 | while (i <= lmcs->max_bin_idx && sample >= lmcs->pivot[i + 1]) |
906 | 5037 | i++; | |
907 | 387072 | i = FFMIN(i, LMCS_MAX_BIN_SIZE - 1); | |
908 | |||
909 | 387072 | inv_sample = lmcs_derive_lut_sample(sample, input_pivot, lmcs->pivot, | |
910 | inv_scale_coeff, i, max); | ||
911 | |||
912 |
1/2✓ Branch 0 taken 387072 times.
✗ Branch 1 not taken.
|
387072 | if (bit_depth > 8) |
913 | 387072 | lmcs->inv_lut.u16[sample] = inv_sample; | |
914 | else | ||
915 | ✗ | lmcs->inv_lut.u8 [sample] = inv_sample; | |
916 | } | ||
917 | |||
918 | 378 | return 0; | |
919 | } | ||
920 | |||
921 | 1066 | static int ph_max_num_subblock_merge_cand(const H266RawSPS *sps, const H266RawPictureHeader *ph) | |
922 | { | ||
923 |
2/2✓ Branch 0 taken 1061 times.
✓ Branch 1 taken 5 times.
|
1066 | if (sps->sps_affine_enabled_flag) |
924 | 1061 | return 5 - sps->sps_five_minus_max_num_subblock_merge_cand; | |
925 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
5 | return sps->sps_sbtmvp_enabled_flag && ph->ph_temporal_mvp_enabled_flag; |
926 | } | ||
927 | |||
928 | 42 | static int ph_vb_pos(uint16_t *vbs, uint8_t *num_vbs, const uint16_t *pos_minus_1, const uint8_t num_pos, uint16_t max, const int ctb_size_y) | |
929 | { | ||
930 | 42 | max = FF_CEIL_RSHIFT(max, 3) - 2; | |
931 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 42 times.
|
42 | for (int i = 0; i < num_pos; i++) { |
932 | ✗ | if (pos_minus_1[i] > max) | |
933 | ✗ | return AVERROR_INVALIDDATA; | |
934 | |||
935 | ✗ | vbs[i] = (pos_minus_1[i] + 1) << 3; | |
936 | |||
937 | // The distance between any two vertical virtual boundaries shall be greater than or equal to CtbSizeY luma samples | ||
938 | ✗ | if (i && vbs[i] < vbs[i - 1] + ctb_size_y) | |
939 | ✗ | return AVERROR_INVALIDDATA; | |
940 | } | ||
941 | 42 | *num_vbs = num_pos; | |
942 | |||
943 | 42 | return 0; | |
944 | } | ||
945 | |||
946 | #define VBF(f) (sps->sps_virtual_boundaries_present_flag ? sps->sps_##f : ph->r->ph_##f) | ||
947 | #define VBFS(c, d) VBF(virtual_boundary_pos_##c##_minus1), VBF(num_##d##_virtual_boundaries) | ||
948 | |||
949 | 1066 | static int ph_vb(VVCPH *ph, const H266RawSPS *sps, const H266RawPPS *pps) | |
950 | { | ||
951 | 1066 | const int ctb_size_y = 1 << (sps->sps_log2_ctu_size_minus5 + 5); | |
952 | int ret; | ||
953 | |||
954 |
2/2✓ Branch 0 taken 1045 times.
✓ Branch 1 taken 21 times.
|
1066 | if (!sps->sps_virtual_boundaries_enabled_flag) |
955 | 1045 | return 0; | |
956 | |||
957 |
2/4✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 21 times.
✗ Branch 3 not taken.
|
21 | ret = ph_vb_pos(ph->vb_pos_x, &ph->num_ver_vbs, VBFS(x, ver), pps->pps_pic_width_in_luma_samples, ctb_size_y); |
958 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
|
21 | if (ret < 0) |
959 | ✗ | return ret; | |
960 | |||
961 |
2/4✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 21 times.
✗ Branch 3 not taken.
|
21 | ret = ph_vb_pos(ph->vb_pos_y, &ph->num_hor_vbs, VBFS(y, hor), pps->pps_pic_height_in_luma_samples, ctb_size_y); |
962 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
|
21 | if (ret < 0) |
963 | ✗ | return ret; | |
964 | |||
965 | 21 | return 0; | |
966 | } | ||
967 | |||
968 | 1066 | static int ph_derive(VVCPH *ph, const H266RawSPS *sps, const H266RawPPS *pps, const int poc_tid0, const int is_clvss) | |
969 | { | ||
970 | int ret; | ||
971 | 1066 | ph->max_num_subblock_merge_cand = ph_max_num_subblock_merge_cand(sps, ph->r); | |
972 | |||
973 | 1066 | ph->poc = ph_compute_poc(ph->r, sps, poc_tid0, is_clvss); | |
974 | |||
975 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1066 times.
|
1066 | if (pps->pps_wp_info_in_ph_flag) |
976 | ✗ | pred_weight_table(&ph->pwt, &ph->r->ph_pred_weight_table); | |
977 | |||
978 | 1066 | ret = ph_vb(ph, sps, pps); | |
979 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1066 times.
|
1066 | if (ret < 0) |
980 | ✗ | return ret; | |
981 | |||
982 | 1066 | return 0; | |
983 | } | ||
984 | |||
985 | 1066 | static int decode_ph(VVCFrameParamSets *fps, const H266RawPictureHeader *rph, void *rph_ref, | |
986 | const int poc_tid0, const int is_clvss) | ||
987 | { | ||
988 | int ret; | ||
989 | 1066 | VVCPH *ph = &fps->ph; | |
990 | 1066 | const H266RawSPS *sps = fps->sps->r; | |
991 | 1066 | const H266RawPPS *pps = fps->pps->r; | |
992 | |||
993 | 1066 | ph->r = rph; | |
994 | 1066 | av_refstruct_replace(&ph->rref, rph_ref); | |
995 | 1066 | ret = ph_derive(ph, sps, pps, poc_tid0, is_clvss); | |
996 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1066 times.
|
1066 | if (ret < 0) |
997 | ✗ | return ret; | |
998 | |||
999 | 1066 | return 0; | |
1000 | } | ||
1001 | |||
1002 | 1066 | static int decode_frame_ps(VVCFrameParamSets *fps, const VVCParamSets *ps, | |
1003 | const SliceContext *sc, const int poc_tid0, const int is_clvss, const VVCContext *s) | ||
1004 | { | ||
1005 | 1066 | const H266RawSlice *sl = sc->ref; | |
1006 | 1066 | const H266RawPictureHeader *ph = sl->ph; | |
1007 | 1066 | const H266RawPPS *rpps = sl->pps; | |
1008 | int ret; | ||
1009 | |||
1010 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1066 times.
|
1066 | if (!ph) |
1011 | ✗ | return AVERROR_INVALIDDATA; | |
1012 | |||
1013 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1066 times.
|
1066 | if (!rpps) |
1014 | ✗ | return AVERROR_INVALIDDATA; | |
1015 | |||
1016 | 1066 | av_refstruct_replace(&fps->sps, ps->sps_list[rpps->pps_seq_parameter_set_id]); | |
1017 | 1066 | av_refstruct_replace(&fps->pps, ps->pps_list[rpps->pps_pic_parameter_set_id]); | |
1018 | |||
1019 | 1066 | ret = decode_ph(fps, ph, sl->ph_ref, poc_tid0, is_clvss); | |
1020 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1066 times.
|
1066 | if (ret < 0) |
1021 | ✗ | return ret; | |
1022 | |||
1023 |
2/2✓ Branch 0 taken 137 times.
✓ Branch 1 taken 929 times.
|
1066 | if (ph->ph_explicit_scaling_list_enabled_flag) |
1024 | 137 | av_refstruct_replace(&fps->sl, ps->scaling_list[ph->ph_scaling_list_aps_id]); | |
1025 | |||
1026 |
2/2✓ Branch 0 taken 378 times.
✓ Branch 1 taken 688 times.
|
1066 | if (ph->ph_lmcs_enabled_flag) { |
1027 | 378 | ret = lmcs_derive_lut(&fps->lmcs, ps->lmcs_list[ph->ph_lmcs_aps_id], fps->sps->r); | |
1028 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 378 times.
|
378 | if (ret < 0) |
1029 | ✗ | return ret; | |
1030 | } | ||
1031 | |||
1032 |
2/2✓ Branch 0 taken 8528 times.
✓ Branch 1 taken 1066 times.
|
9594 | for (int i = 0; i < FF_ARRAY_ELEMS(fps->alf_list); i++) |
1033 | 8528 | av_refstruct_replace(&fps->alf_list[i], ps->alf_list[i]); | |
1034 | |||
1035 | 1066 | return 0; | |
1036 | } | ||
1037 | |||
1038 | 1066 | static void decode_recovery_flag(VVCContext *s) | |
1039 | { | ||
1040 |
4/4✓ Branch 0 taken 1059 times.
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 96 times.
✓ Branch 3 taken 963 times.
|
1066 | if (IS_IDR(s)) |
1041 | 103 | s->no_output_before_recovery_flag = 1; | |
1042 |
4/4✓ Branch 0 taken 951 times.
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 948 times.
|
963 | else if (IS_CRA(s) || IS_GDR(s)) |
1043 | 15 | s->no_output_before_recovery_flag = s->last_eos; | |
1044 | 1066 | } | |
1045 | |||
1046 | 1066 | static void decode_recovery_poc(VVCContext *s, const VVCPH *ph) | |
1047 | { | ||
1048 |
2/2✓ Branch 0 taken 865 times.
✓ Branch 1 taken 201 times.
|
1066 | if (s->no_output_before_recovery_flag) { |
1049 |
2/2✓ Branch 0 taken 3 times.
✓ Branch 1 taken 862 times.
|
865 | if (IS_GDR(s)) |
1050 | 3 | s->gdr_recovery_point_poc = ph->poc + ph->r->ph_recovery_poc_cnt; | |
1051 |
3/4✓ Branch 0 taken 3 times.
✓ Branch 1 taken 862 times.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
|
865 | if (!GDR_IS_RECOVERED(s) && s->gdr_recovery_point_poc <= ph->poc) |
1052 | 3 | GDR_SET_RECOVERED(s); | |
1053 | } | ||
1054 | 1066 | } | |
1055 | |||
1056 | 1066 | int ff_vvc_decode_frame_ps(struct VVCFrameContext *fc, struct VVCContext *s) | |
1057 | { | ||
1058 | 1066 | int ret = 0; | |
1059 | 1066 | VVCFrameParamSets *fps = &fc->ps; | |
1060 | 1066 | VVCParamSets *ps = &s->ps; | |
1061 | 1066 | const SliceContext *sc = fc->slices[0]; | |
1062 | int is_clvss; | ||
1063 | |||
1064 | 1066 | decode_recovery_flag(s); | |
1065 |
10/10✓ Branch 0 taken 1059 times.
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 963 times.
✓ Branch 3 taken 96 times.
✓ Branch 4 taken 951 times.
✓ Branch 5 taken 12 times.
✓ Branch 6 taken 3 times.
✓ Branch 7 taken 948 times.
✓ Branch 8 taken 109 times.
✓ Branch 9 taken 9 times.
|
1066 | is_clvss = IS_CLVSS(s); |
1066 | |||
1067 | 1066 | ret = decode_ps(ps, s->avctx, sc, is_clvss); | |
1068 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1066 times.
|
1066 | if (ret < 0) |
1069 | ✗ | return ret; | |
1070 | |||
1071 | 1066 | ret = decode_frame_ps(fps, ps, sc, s->poc_tid0, is_clvss, s); | |
1072 | 1066 | decode_recovery_poc(s, &fps->ph); | |
1073 | 1066 | return ret; | |
1074 | } | ||
1075 | |||
1076 | 752 | void ff_vvc_frame_ps_free(VVCFrameParamSets *fps) | |
1077 | { | ||
1078 | 752 | av_refstruct_unref(&fps->sps); | |
1079 | 752 | av_refstruct_unref(&fps->pps); | |
1080 | 752 | av_refstruct_unref(&fps->ph.rref); | |
1081 | 752 | av_refstruct_unref(&fps->sl); | |
1082 |
2/2✓ Branch 0 taken 6016 times.
✓ Branch 1 taken 752 times.
|
6768 | for (int i = 0; i < FF_ARRAY_ELEMS(fps->alf_list); i++) |
1083 | 6016 | av_refstruct_unref(&fps->alf_list[i]); | |
1084 | 752 | } | |
1085 | |||
1086 | 94 | void ff_vvc_ps_uninit(VVCParamSets *ps) | |
1087 | { | ||
1088 |
2/2✓ Branch 0 taken 752 times.
✓ Branch 1 taken 94 times.
|
846 | for (int i = 0; i < FF_ARRAY_ELEMS(ps->scaling_list); i++) |
1089 | 752 | av_refstruct_unref(&ps->scaling_list[i]); | |
1090 |
2/2✓ Branch 0 taken 376 times.
✓ Branch 1 taken 94 times.
|
470 | for (int i = 0; i < FF_ARRAY_ELEMS(ps->lmcs_list); i++) |
1091 | 376 | av_refstruct_unref(&ps->lmcs_list[i]); | |
1092 |
2/2✓ Branch 0 taken 752 times.
✓ Branch 1 taken 94 times.
|
846 | for (int i = 0; i < FF_ARRAY_ELEMS(ps->alf_list); i++) |
1093 | 752 | av_refstruct_unref(&ps->alf_list[i]); | |
1094 |
2/2✓ Branch 0 taken 1504 times.
✓ Branch 1 taken 94 times.
|
1598 | for (int i = 0; i < FF_ARRAY_ELEMS(ps->sps_list); i++) |
1095 | 1504 | av_refstruct_unref(&ps->sps_list[i]); | |
1096 |
2/2✓ Branch 0 taken 6016 times.
✓ Branch 1 taken 94 times.
|
6110 | for (int i = 0; i < FF_ARRAY_ELEMS(ps->pps_list); i++) |
1097 | 6016 | av_refstruct_unref(&ps->pps_list[i]); | |
1098 | 94 | } | |
1099 | |||
1100 | 7603 | static void alf_coeff(int16_t *coeff, | |
1101 | const uint8_t *abs, const uint8_t *sign, const int size) | ||
1102 | { | ||
1103 |
2/2✓ Branch 0 taken 86868 times.
✓ Branch 1 taken 7603 times.
|
94471 | for (int i = 0; i < size; i++) |
1104 | 86868 | coeff[i] = (1 - 2 * sign[i]) * abs[i]; | |
1105 | 7603 | } | |
1106 | |||
1107 | 830 | static void alf_coeff_cc(int16_t *coeff, | |
1108 | const uint8_t *mapped_abs, const uint8_t *sign) | ||
1109 | { | ||
1110 |
2/2✓ Branch 0 taken 5810 times.
✓ Branch 1 taken 830 times.
|
6640 | for (int i = 0; i < ALF_NUM_COEFF_CC; i++) { |
1111 | 5810 | int c = mapped_abs[i]; | |
1112 |
2/2✓ Branch 0 taken 4996 times.
✓ Branch 1 taken 814 times.
|
5810 | if (c) |
1113 | 4996 | c = (1 - 2 * sign[i]) * (1 << (c - 1)); | |
1114 | 5810 | coeff[i] = c; | |
1115 | } | ||
1116 | 830 | } | |
1117 | |||
1118 | 326 | static void alf_luma(VVCALF *alf, const H266RawAPS *aps) | |
1119 | { | ||
1120 |
2/2✓ Branch 0 taken 51 times.
✓ Branch 1 taken 275 times.
|
326 | if (!aps->alf_luma_filter_signal_flag) |
1121 | 51 | return; | |
1122 | |||
1123 |
2/2✓ Branch 0 taken 6875 times.
✓ Branch 1 taken 275 times.
|
7150 | for (int i = 0; i < ALF_NUM_FILTERS_LUMA; i++) { |
1124 | 6875 | const int ref = aps->alf_luma_coeff_delta_idx[i]; | |
1125 | 6875 | const uint8_t *abs = aps->alf_luma_coeff_abs[ref]; | |
1126 | 6875 | const uint8_t *sign = aps->alf_luma_coeff_sign[ref]; | |
1127 | |||
1128 | 6875 | alf_coeff(alf->luma_coeff[i], abs, sign, ALF_NUM_COEFF_LUMA); | |
1129 | 6875 | memcpy(alf->luma_clip_idx[i], aps->alf_luma_clip_idx[ref], | |
1130 | sizeof(alf->luma_clip_idx[i])); | ||
1131 | } | ||
1132 | } | ||
1133 | |||
1134 | 326 | static void alf_chroma(VVCALF *alf, const H266RawAPS *aps) | |
1135 | { | ||
1136 |
2/2✓ Branch 0 taken 90 times.
✓ Branch 1 taken 236 times.
|
326 | if (!aps->alf_chroma_filter_signal_flag) |
1137 | 90 | return; | |
1138 | |||
1139 | 236 | alf->num_chroma_filters = aps->alf_chroma_num_alt_filters_minus1 + 1; | |
1140 |
2/2✓ Branch 0 taken 728 times.
✓ Branch 1 taken 236 times.
|
964 | for (int i = 0; i < alf->num_chroma_filters; i++) { |
1141 | 728 | const uint8_t *abs = aps->alf_chroma_coeff_abs[i]; | |
1142 | 728 | const uint8_t *sign = aps->alf_chroma_coeff_sign[i]; | |
1143 | |||
1144 | 728 | alf_coeff(alf->chroma_coeff[i], abs, sign, ALF_NUM_COEFF_CHROMA); | |
1145 | 728 | memcpy(alf->chroma_clip_idx[i], aps->alf_chroma_clip_idx[i], | |
1146 | sizeof(alf->chroma_clip_idx[i])); | ||
1147 | } | ||
1148 | } | ||
1149 | |||
1150 | 326 | static void alf_cc(VVCALF *alf, const H266RawAPS *aps) | |
1151 | { | ||
1152 | 326 | const uint8_t (*abs[])[ALF_NUM_COEFF_CC] = | |
1153 | 326 | { aps->alf_cc_cb_mapped_coeff_abs, aps->alf_cc_cr_mapped_coeff_abs }; | |
1154 | 326 | const uint8_t (*sign[])[ALF_NUM_COEFF_CC] = | |
1155 | 326 | {aps->alf_cc_cb_coeff_sign, aps->alf_cc_cr_coeff_sign }; | |
1156 | 326 | const int signaled[] = { aps->alf_cc_cb_filter_signal_flag, aps->alf_cc_cr_filter_signal_flag}; | |
1157 | |||
1158 | 326 | alf->num_cc_filters[0] = aps->alf_cc_cb_filters_signalled_minus1 + 1; | |
1159 | 326 | alf->num_cc_filters[1] = aps->alf_cc_cr_filters_signalled_minus1 + 1; | |
1160 | |||
1161 |
2/2✓ Branch 0 taken 652 times.
✓ Branch 1 taken 326 times.
|
978 | for (int idx = 0; idx < 2; idx++) { |
1162 |
2/2✓ Branch 0 taken 276 times.
✓ Branch 1 taken 376 times.
|
652 | if (signaled[idx]) { |
1163 |
2/2✓ Branch 0 taken 830 times.
✓ Branch 1 taken 276 times.
|
1106 | for (int i = 0; i < alf->num_cc_filters[idx]; i++) |
1164 | 830 | alf_coeff_cc(alf->cc_coeff[idx][i], abs[idx][i], sign[idx][i]); | |
1165 | } | ||
1166 | } | ||
1167 | 326 | } | |
1168 | |||
1169 | 326 | static void alf_derive(VVCALF *alf, const H266RawAPS *aps) | |
1170 | { | ||
1171 | 326 | alf_luma(alf, aps); | |
1172 | 326 | alf_chroma(alf, aps); | |
1173 | 326 | alf_cc(alf, aps); | |
1174 | 326 | } | |
1175 | |||
1176 | 326 | static void alf_free(AVRefStructOpaque unused, void *obj) | |
1177 | { | ||
1178 | 326 | VVCALF *alf = obj; | |
1179 | |||
1180 | 326 | av_refstruct_unref(&alf->r); | |
1181 | 326 | } | |
1182 | |||
1183 | 326 | static int aps_decode_alf(const VVCALF **alf, const H266RawAPS *aps) | |
1184 | { | ||
1185 | 326 | VVCALF *a = av_refstruct_alloc_ext(sizeof(*a), 0, NULL, alf_free); | |
1186 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 326 times.
|
326 | if (!a) |
1187 | ✗ | return AVERROR(ENOMEM); | |
1188 | |||
1189 | 326 | alf_derive(a, aps); | |
1190 | 326 | av_refstruct_replace(&a->r, aps); | |
1191 | 326 | av_refstruct_replace(alf, a); | |
1192 | 326 | av_refstruct_unref(&a); | |
1193 | |||
1194 | 326 | return 0; | |
1195 | } | ||
1196 | |||
1197 | 280 | static int is_luma_list(const int id) | |
1198 | { | ||
1199 |
4/4✓ Branch 0 taken 190 times.
✓ Branch 1 taken 90 times.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 180 times.
|
280 | return id % VVC_MAX_SAMPLE_ARRAYS == SL_START_4x4 || id == SL_START_64x64 + 1; |
1200 | } | ||
1201 | |||
1202 | 448 | static int derive_matrix_size(const int id) | |
1203 | { | ||
1204 |
4/4✓ Branch 0 taken 416 times.
✓ Branch 1 taken 32 times.
✓ Branch 2 taken 96 times.
✓ Branch 3 taken 320 times.
|
448 | return id < SL_START_4x4 ? 2 : (id < SL_START_8x8 ? 4 : 8); |
1205 | } | ||
1206 | |||
1207 | // 7.4.3.20 Scaling list data semantics | ||
1208 | 16 | static void scaling_derive(VVCScalingList *sl, const H266RawAPS *aps) | |
1209 | { | ||
1210 |
2/2✓ Branch 0 taken 448 times.
✓ Branch 1 taken 16 times.
|
464 | for (int id = 0; id < SL_MAX_ID; id++) { |
1211 | 448 | const int matrix_size = derive_matrix_size(id); | |
1212 | 448 | const int log2_size = av_log2(matrix_size); | |
1213 | 448 | const int list_size = matrix_size * matrix_size; | |
1214 | int coeff[SL_MAX_MATRIX_SIZE * SL_MAX_MATRIX_SIZE]; | ||
1215 | const uint8_t *pred; | ||
1216 | const int *scaling_list; | ||
1217 | 448 | int dc = 0; | |
1218 | |||
1219 |
4/4✓ Branch 0 taken 280 times.
✓ Branch 1 taken 168 times.
✓ Branch 3 taken 100 times.
✓ Branch 4 taken 180 times.
|
448 | if (aps->aps_chroma_present_flag || is_luma_list(id)) { |
1220 |
2/2✓ Branch 0 taken 122 times.
✓ Branch 1 taken 146 times.
|
268 | if (!aps->scaling_list_copy_mode_flag[id]) { |
1221 | 122 | int next_coef = 0; | |
1222 | |||
1223 |
2/2✓ Branch 0 taken 36 times.
✓ Branch 1 taken 86 times.
|
122 | if (id >= SL_START_16x16) |
1224 | 36 | dc = next_coef = aps->scaling_list_dc_coef[id - SL_START_16x16]; | |
1225 | |||
1226 |
2/2✓ Branch 0 taken 5504 times.
✓ Branch 1 taken 122 times.
|
5626 | for (int i = 0; i < list_size; i++) { |
1227 | 5504 | const int x = ff_vvc_diag_scan_x[3][3][i]; | |
1228 | 5504 | const int y = ff_vvc_diag_scan_y[3][3][i]; | |
1229 | |||
1230 |
6/6✓ Branch 0 taken 384 times.
✓ Branch 1 taken 5120 times.
✓ Branch 2 taken 192 times.
✓ Branch 3 taken 192 times.
✓ Branch 4 taken 96 times.
✓ Branch 5 taken 96 times.
|
5504 | if (!(id >= SL_START_64x64 && x >= 4 && y >= 4)) |
1231 | 5408 | next_coef += aps->scaling_list_delta_coef[id][i]; | |
1232 | 5504 | coeff[i] = next_coef; | |
1233 | } | ||
1234 | } | ||
1235 | } | ||
1236 | |||
1237 | //dc | ||
1238 |
2/2✓ Branch 0 taken 224 times.
✓ Branch 1 taken 224 times.
|
448 | if (id >= SL_START_16x16) { |
1239 |
4/4✓ Branch 0 taken 36 times.
✓ Branch 1 taken 188 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 32 times.
|
224 | if (!aps->scaling_list_copy_mode_flag[id] && !aps->scaling_list_pred_mode_flag[id]) { |
1240 | 4 | dc += 8; | |
1241 |
2/2✓ Branch 0 taken 80 times.
✓ Branch 1 taken 140 times.
|
220 | } else if (!aps->scaling_list_pred_id_delta[id]) { |
1242 | 80 | dc += 16; | |
1243 | } else { | ||
1244 | 140 | const int ref_id = id - aps->scaling_list_pred_id_delta[id]; | |
1245 |
2/2✓ Branch 0 taken 94 times.
✓ Branch 1 taken 46 times.
|
140 | if (ref_id >= SL_START_16x16) |
1246 | 94 | dc += sl->scaling_matrix_dc_rec[ref_id - SL_START_16x16]; | |
1247 | else | ||
1248 | 46 | dc += sl->scaling_matrix_rec[ref_id][0]; | |
1249 | } | ||
1250 | 224 | sl->scaling_matrix_dc_rec[id - SL_START_16x16] = dc & 255; | |
1251 | } | ||
1252 | |||
1253 | //ac | ||
1254 |
2/2✓ Branch 0 taken 122 times.
✓ Branch 1 taken 326 times.
|
448 | scaling_list = aps->scaling_list_copy_mode_flag[id] ? ff_vvc_scaling_list0 : coeff; |
1255 |
4/4✓ Branch 0 taken 122 times.
✓ Branch 1 taken 326 times.
✓ Branch 2 taken 46 times.
✓ Branch 3 taken 76 times.
|
448 | if (!aps->scaling_list_copy_mode_flag[id] && !aps->scaling_list_pred_mode_flag[id]) |
1256 | 46 | pred = ff_vvc_scaling_pred_8; | |
1257 |
2/2✓ Branch 0 taken 194 times.
✓ Branch 1 taken 208 times.
|
402 | else if (!aps->scaling_list_pred_id_delta[id]) |
1258 | 194 | pred = ff_vvc_scaling_pred_16; | |
1259 | else | ||
1260 | 208 | pred = sl->scaling_matrix_rec[id - aps->scaling_list_pred_id_delta[id]]; | |
1261 |
2/2✓ Branch 0 taken 22144 times.
✓ Branch 1 taken 448 times.
|
22592 | for (int i = 0; i < list_size; i++) { |
1262 | 22144 | const int x = ff_vvc_diag_scan_x[log2_size][log2_size][i]; | |
1263 | 22144 | const int y = ff_vvc_diag_scan_y[log2_size][log2_size][i]; | |
1264 | 22144 | const int off = y * matrix_size + x; | |
1265 | 22144 | sl->scaling_matrix_rec[id][off] = (pred[off] + scaling_list[i]) & 255; | |
1266 | } | ||
1267 | } | ||
1268 | 16 | } | |
1269 | |||
1270 | 16 | static int aps_decode_scaling(const VVCScalingList **scaling, const H266RawAPS *aps) | |
1271 | { | ||
1272 | 16 | VVCScalingList *sl = av_refstruct_allocz(sizeof(*sl)); | |
1273 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
|
16 | if (!sl) |
1274 | ✗ | return AVERROR(ENOMEM); | |
1275 | |||
1276 | 16 | scaling_derive(sl, aps); | |
1277 | 16 | av_refstruct_replace(scaling, sl); | |
1278 | 16 | av_refstruct_unref(&sl); | |
1279 | |||
1280 | 16 | return 0; | |
1281 | } | ||
1282 | |||
1283 | 427 | int ff_vvc_decode_aps(VVCParamSets *ps, const CodedBitstreamUnit *unit) | |
1284 | { | ||
1285 | 427 | const H266RawAPS *aps = unit->content_ref; | |
1286 | 427 | int ret = 0; | |
1287 | |||
1288 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 427 times.
|
427 | if (!aps) |
1289 | ✗ | return AVERROR_INVALIDDATA; | |
1290 | |||
1291 |
3/4✓ Branch 0 taken 326 times.
✓ Branch 1 taken 85 times.
✓ Branch 2 taken 16 times.
✗ Branch 3 not taken.
|
427 | switch (aps->aps_params_type) { |
1292 | 326 | case VVC_ASP_TYPE_ALF: | |
1293 | 326 | ret = aps_decode_alf(&ps->alf_list[aps->aps_adaptation_parameter_set_id], aps); | |
1294 | 326 | break; | |
1295 | 85 | case VVC_ASP_TYPE_LMCS: | |
1296 | 85 | av_refstruct_replace(&ps->lmcs_list[aps->aps_adaptation_parameter_set_id], aps); | |
1297 | 85 | break; | |
1298 | 16 | case VVC_ASP_TYPE_SCALING: | |
1299 | 16 | ret = aps_decode_scaling(&ps->scaling_list[aps->aps_adaptation_parameter_set_id], aps); | |
1300 | 16 | break; | |
1301 | } | ||
1302 | |||
1303 | 427 | return ret; | |
1304 | } | ||
1305 | |||
1306 | 1831 | static int sh_alf_aps(const VVCSH *sh, const VVCFrameParamSets *fps) | |
1307 | { | ||
1308 |
2/2✓ Branch 0 taken 422 times.
✓ Branch 1 taken 1409 times.
|
1831 | if (!sh->r->sh_alf_enabled_flag) |
1309 | 422 | return 0; | |
1310 | |||
1311 |
2/2✓ Branch 0 taken 1735 times.
✓ Branch 1 taken 1409 times.
|
3144 | for (int i = 0; i < sh->r->sh_num_alf_aps_ids_luma; i++) { |
1312 | 1735 | const VVCALF *alf_aps_luma = fps->alf_list[sh->r->sh_alf_aps_id_luma[i]]; | |
1313 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1735 times.
|
1735 | if (!alf_aps_luma) |
1314 | ✗ | return AVERROR_INVALIDDATA; | |
1315 | } | ||
1316 | |||
1317 |
4/4✓ Branch 0 taken 753 times.
✓ Branch 1 taken 656 times.
✓ Branch 2 taken 152 times.
✓ Branch 3 taken 601 times.
|
1409 | if (sh->r->sh_alf_cb_enabled_flag || sh->r->sh_alf_cr_enabled_flag) { |
1318 | 808 | const VVCALF *alf_aps_chroma = fps->alf_list[sh->r->sh_alf_aps_id_chroma]; | |
1319 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 808 times.
|
808 | if (!alf_aps_chroma) |
1320 | ✗ | return AVERROR_INVALIDDATA; | |
1321 | } | ||
1322 | |||
1323 |
2/2✓ Branch 0 taken 1350 times.
✓ Branch 1 taken 59 times.
|
1409 | if (fps->sps->r->sps_ccalf_enabled_flag) { |
1324 |
2/2✓ Branch 0 taken 216 times.
✓ Branch 1 taken 1134 times.
|
1350 | if (sh->r->sh_alf_cc_cb_enabled_flag) { |
1325 | 216 | const VVCALF *alf_aps_cc_cr = fps->alf_list[sh->r->sh_alf_cc_cb_aps_id]; | |
1326 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 216 times.
|
216 | if (!alf_aps_cc_cr) |
1327 | ✗ | return AVERROR_INVALIDDATA; | |
1328 | } | ||
1329 |
2/2✓ Branch 0 taken 188 times.
✓ Branch 1 taken 1162 times.
|
1350 | if (sh->r->sh_alf_cc_cr_enabled_flag) { |
1330 | 188 | const VVCALF *alf_aps_cc_cr = fps->alf_list[sh->r->sh_alf_cc_cr_aps_id]; | |
1331 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 188 times.
|
188 | if (!alf_aps_cc_cr) |
1332 | ✗ | return AVERROR_INVALIDDATA; | |
1333 | } | ||
1334 | } | ||
1335 | |||
1336 | 1409 | return 0; | |
1337 | } | ||
1338 | |||
1339 | 1831 | static int sh_slice_address(VVCSH *sh, const H266RawSPS *sps, const VVCPPS *pps) | |
1340 | { | ||
1341 | 1831 | const int slice_address = sh->r->sh_slice_address; | |
1342 | |||
1343 |
2/2✓ Branch 0 taken 684 times.
✓ Branch 1 taken 1147 times.
|
1831 | if (pps->r->pps_rect_slice_flag) { |
1344 | 684 | int pic_level_slice_idx = slice_address; | |
1345 |
2/2✓ Branch 0 taken 1047 times.
✓ Branch 1 taken 684 times.
|
1731 | for (int j = 0; j < sh->r->curr_subpic_idx; j++) |
1346 | 1047 | pic_level_slice_idx += pps->r->num_slices_in_subpic[j]; | |
1347 | 684 | sh->ctb_addr_in_curr_slice = pps->ctb_addr_in_slice + pps->slice_start_offset[pic_level_slice_idx]; | |
1348 | 684 | sh->num_ctus_in_curr_slice = pps->num_ctus_in_slice[pic_level_slice_idx]; | |
1349 | } else { | ||
1350 | 1147 | int tile_x = slice_address % pps->r->num_tile_columns; | |
1351 | 1147 | int tile_y = slice_address / pps->r->num_tile_columns; | |
1352 | 1147 | const int slice_start_ctb = pps->row_bd[tile_y] * pps->ctb_width + pps->col_bd[tile_x] * pps->r->row_height_val[tile_y]; | |
1353 | |||
1354 | 1147 | sh->ctb_addr_in_curr_slice = pps->ctb_addr_in_slice + slice_start_ctb; | |
1355 | |||
1356 | 1147 | sh->num_ctus_in_curr_slice = 0; | |
1357 |
2/2✓ Branch 0 taken 1227 times.
✓ Branch 1 taken 1147 times.
|
2374 | for (int tile_idx = slice_address; tile_idx <= slice_address + sh->r->sh_num_tiles_in_slice_minus1; tile_idx++) { |
1358 | 1227 | tile_x = tile_idx % pps->r->num_tile_columns; | |
1359 | 1227 | tile_y = tile_idx / pps->r->num_tile_columns; | |
1360 | 1227 | sh->num_ctus_in_curr_slice += pps->r->row_height_val[tile_y] * pps->r->col_width_val[tile_x]; | |
1361 | } | ||
1362 | } | ||
1363 | |||
1364 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1831 times.
|
1831 | if (!sh->num_ctus_in_curr_slice) |
1365 | ✗ | return AVERROR_INVALIDDATA; | |
1366 | |||
1367 | 1831 | return 0; | |
1368 | } | ||
1369 | |||
1370 | 1831 | static void sh_qp_y(VVCSH *sh, const H266RawPPS *pps, const H266RawPictureHeader *ph) | |
1371 | { | ||
1372 | 1831 | const int init_qp = pps->pps_init_qp_minus26 + 26; | |
1373 | |||
1374 |
2/2✓ Branch 0 taken 1561 times.
✓ Branch 1 taken 270 times.
|
1831 | if (!pps->pps_qp_delta_info_in_ph_flag) |
1375 | 1561 | sh->slice_qp_y = init_qp + sh->r->sh_qp_delta; | |
1376 | else | ||
1377 | 270 | sh->slice_qp_y = init_qp + ph->ph_qp_delta; | |
1378 | 1831 | } | |
1379 | |||
1380 | 1831 | static void sh_inter(VVCSH *sh, const H266RawSPS *sps, const H266RawPPS *pps) | |
1381 | { | ||
1382 | 1831 | const H266RawSliceHeader *rsh = sh->r; | |
1383 | |||
1384 |
1/2✓ Branch 0 taken 1831 times.
✗ Branch 1 not taken.
|
1831 | if (!pps->pps_wp_info_in_ph_flag && |
1385 |
4/4✓ Branch 0 taken 82 times.
✓ Branch 1 taken 1749 times.
✓ Branch 2 taken 70 times.
✓ Branch 3 taken 12 times.
|
1831 | ((pps->pps_weighted_pred_flag && IS_P(rsh)) || |
1386 |
4/4✓ Branch 0 taken 70 times.
✓ Branch 1 taken 1749 times.
✓ Branch 2 taken 61 times.
✓ Branch 3 taken 9 times.
|
1819 | (pps->pps_weighted_bipred_flag && IS_B(rsh)))) |
1387 | 73 | pred_weight_table(&sh->pwt, &rsh->sh_pred_weight_table); | |
1388 | 1831 | } | |
1389 | |||
1390 | 1831 | static void sh_deblock_offsets(VVCSH *sh) | |
1391 | { | ||
1392 | 1831 | const H266RawSliceHeader *r = sh->r; | |
1393 | |||
1394 |
2/2✓ Branch 0 taken 1830 times.
✓ Branch 1 taken 1 times.
|
1831 | if (!r->sh_deblocking_filter_disabled_flag) { |
1395 | 1830 | sh->deblock.beta_offset[LUMA] = r->sh_luma_beta_offset_div2 * 2; | |
1396 | 1830 | sh->deblock.tc_offset[LUMA] = r->sh_luma_tc_offset_div2 * 2; | |
1397 | 1830 | sh->deblock.beta_offset[CB] = r->sh_cb_beta_offset_div2 * 2; | |
1398 | 1830 | sh->deblock.tc_offset[CB] = r->sh_cb_tc_offset_div2 * 2; | |
1399 | 1830 | sh->deblock.beta_offset[CR] = r->sh_cr_beta_offset_div2 * 2; | |
1400 | 1830 | sh->deblock.tc_offset[CR] = r->sh_cr_tc_offset_div2 * 2; | |
1401 | } | ||
1402 | 1831 | } | |
1403 | |||
1404 | 1831 | static void sh_partition_constraints(VVCSH *sh, const H266RawSPS *sps, const H266RawPictureHeader *ph) | |
1405 | { | ||
1406 | 1831 | const int min_cb_log2_size_y = sps->sps_log2_min_luma_coding_block_size_minus2 + 2; | |
1407 | int min_qt_log2_size_y[2]; | ||
1408 | |||
1409 |
2/2✓ Branch 0 taken 284 times.
✓ Branch 1 taken 1547 times.
|
1831 | if (IS_I(sh->r)) { |
1410 | 284 | min_qt_log2_size_y[LUMA] = (min_cb_log2_size_y + ph->ph_log2_diff_min_qt_min_cb_intra_slice_luma); | |
1411 | 284 | min_qt_log2_size_y[CHROMA] = (min_cb_log2_size_y + ph->ph_log2_diff_min_qt_min_cb_intra_slice_chroma); | |
1412 | |||
1413 | 284 | sh->max_bt_size[LUMA] = 1 << (min_qt_log2_size_y[LUMA] + ph->ph_log2_diff_max_bt_min_qt_intra_slice_luma); | |
1414 | 284 | sh->max_bt_size[CHROMA] = 1 << (min_qt_log2_size_y[CHROMA]+ ph->ph_log2_diff_max_bt_min_qt_intra_slice_chroma); | |
1415 | |||
1416 | 284 | sh->max_tt_size[LUMA] = 1 << (min_qt_log2_size_y[LUMA] + ph->ph_log2_diff_max_tt_min_qt_intra_slice_luma); | |
1417 | 284 | sh->max_tt_size[CHROMA] = 1 << (min_qt_log2_size_y[CHROMA]+ ph->ph_log2_diff_max_tt_min_qt_intra_slice_chroma); | |
1418 | |||
1419 | 284 | sh->max_mtt_depth[LUMA] = ph->ph_max_mtt_hierarchy_depth_intra_slice_luma; | |
1420 | 284 | sh->max_mtt_depth[CHROMA] = ph->ph_max_mtt_hierarchy_depth_intra_slice_chroma; | |
1421 | |||
1422 | 284 | sh->cu_qp_delta_subdiv = ph->ph_cu_qp_delta_subdiv_intra_slice; | |
1423 | 284 | sh->cu_chroma_qp_offset_subdiv = ph->ph_cu_chroma_qp_offset_subdiv_intra_slice; | |
1424 | } else { | ||
1425 |
2/2✓ Branch 0 taken 3094 times.
✓ Branch 1 taken 1547 times.
|
4641 | for (int i = LUMA; i <= CHROMA; i++) { |
1426 | 3094 | min_qt_log2_size_y[i] = (min_cb_log2_size_y + ph->ph_log2_diff_min_qt_min_cb_inter_slice); | |
1427 | 3094 | sh->max_bt_size[i] = 1 << (min_qt_log2_size_y[i] + ph->ph_log2_diff_max_bt_min_qt_inter_slice); | |
1428 | 3094 | sh->max_tt_size[i] = 1 << (min_qt_log2_size_y[i] + ph->ph_log2_diff_max_tt_min_qt_inter_slice); | |
1429 | 3094 | sh->max_mtt_depth[i] = ph->ph_max_mtt_hierarchy_depth_inter_slice; | |
1430 | } | ||
1431 | |||
1432 | 1547 | sh->cu_qp_delta_subdiv = ph->ph_cu_qp_delta_subdiv_inter_slice; | |
1433 | 1547 | sh->cu_chroma_qp_offset_subdiv = ph->ph_cu_chroma_qp_offset_subdiv_inter_slice; | |
1434 | } | ||
1435 | |||
1436 | 1831 | sh->min_qt_size[LUMA] = 1 << min_qt_log2_size_y[LUMA]; | |
1437 | 1831 | sh->min_qt_size[CHROMA] = 1 << min_qt_log2_size_y[CHROMA]; | |
1438 | 1831 | } | |
1439 | |||
1440 | 1831 | static void sh_entry_points(VVCSH *sh, const H266RawSPS *sps, const VVCPPS *pps) | |
1441 | { | ||
1442 |
2/2✓ Branch 0 taken 1737 times.
✓ Branch 1 taken 94 times.
|
1831 | if (sps->sps_entry_point_offsets_present_flag) { |
1443 |
2/2✓ Branch 0 taken 49469 times.
✓ Branch 1 taken 1737 times.
|
51206 | for (int i = 1, j = 0; i < sh->num_ctus_in_curr_slice; i++) { |
1444 | 49469 | const int pre_ctb_addr_x = sh->ctb_addr_in_curr_slice[i - 1] % pps->ctb_width; | |
1445 | 49469 | const int pre_ctb_addr_y = sh->ctb_addr_in_curr_slice[i - 1] / pps->ctb_width; | |
1446 | 49469 | const int ctb_addr_x = sh->ctb_addr_in_curr_slice[i] % pps->ctb_width; | |
1447 | 49469 | const int ctb_addr_y = sh->ctb_addr_in_curr_slice[i] / pps->ctb_width; | |
1448 |
2/2✓ Branch 0 taken 49426 times.
✓ Branch 1 taken 43 times.
|
49469 | if (pps->ctb_to_row_bd[ctb_addr_y] != pps->ctb_to_row_bd[pre_ctb_addr_y] || |
1449 |
4/4✓ Branch 0 taken 49249 times.
✓ Branch 1 taken 177 times.
✓ Branch 2 taken 3763 times.
✓ Branch 3 taken 45486 times.
|
49426 | pps->ctb_to_col_bd[ctb_addr_x] != pps->ctb_to_col_bd[pre_ctb_addr_x] || |
1450 |
2/2✓ Branch 0 taken 153 times.
✓ Branch 1 taken 3610 times.
|
3763 | (ctb_addr_y != pre_ctb_addr_y && sps->sps_entropy_coding_sync_enabled_flag)) { |
1451 | 373 | sh->entry_point_start_ctu[j++] = i; | |
1452 | } | ||
1453 | } | ||
1454 | } | ||
1455 | 1831 | } | |
1456 | |||
1457 | 1831 | static int sh_derive(VVCSH *sh, const VVCFrameParamSets *fps) | |
1458 | { | ||
1459 | 1831 | const H266RawSPS *sps = fps->sps->r; | |
1460 | 1831 | const H266RawPPS *pps = fps->pps->r; | |
1461 | 1831 | const H266RawPictureHeader *ph = fps->ph.r; | |
1462 | int ret; | ||
1463 | |||
1464 | 1831 | ret = sh_slice_address(sh, sps, fps->pps); | |
1465 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1831 times.
|
1831 | if (ret < 0) |
1466 | ✗ | return ret; | |
1467 | 1831 | ret = sh_alf_aps(sh, fps); | |
1468 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1831 times.
|
1831 | if (ret < 0) |
1469 | ✗ | return ret; | |
1470 | 1831 | sh_inter(sh, sps, pps); | |
1471 | 1831 | sh_qp_y(sh, pps, ph); | |
1472 | 1831 | sh_deblock_offsets(sh); | |
1473 | 1831 | sh_partition_constraints(sh, sps, ph); | |
1474 | 1831 | sh_entry_points(sh, sps, fps->pps); | |
1475 | |||
1476 | 1831 | return 0; | |
1477 | } | ||
1478 | |||
1479 | 1831 | int ff_vvc_decode_sh(VVCSH *sh, const VVCFrameParamSets *fps, const CodedBitstreamUnit *unit) | |
1480 | { | ||
1481 | int ret; | ||
1482 | |||
1483 |
2/4✓ Branch 0 taken 1831 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1831 times.
|
1831 | if (!fps->sps || !fps->pps) |
1484 | ✗ | return AVERROR_INVALIDDATA; | |
1485 | |||
1486 | 1831 | av_refstruct_replace(&sh->r, unit->content_ref); | |
1487 | |||
1488 | 1831 | ret = sh_derive(sh, fps); | |
1489 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1831 times.
|
1831 | if (ret < 0) |
1490 | ✗ | return ret; | |
1491 | |||
1492 | 1831 | return 0; | |
1493 | } | ||
1494 |