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