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