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