../../../ffmpeg/
Coverage:
low: ≥ 0%
medium: ≥ 75.0%
high: ≥ 90.0%
Lines:
0 / 529
0.0%
Branches:
0 / 160
0.0%
Functions:
0 / 11
0.0%

libavcodec/vulkan_hevc.c
Line Branch Exec Source
1 /*
2 * This file is part of FFmpeg.
3 *
4 * FFmpeg is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * FFmpeg is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with FFmpeg; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19 #include "libavutil/mem.h"
20 #include "hevc/hevcdec.h"
21 #include "hevc/data.h"
22 #include "hevc/ps.h"
23
24 #include "vulkan_decode.h"
25
26 const FFVulkanDecodeDescriptor ff_vk_dec_hevc_desc = {
27 .codec_id = AV_CODEC_ID_HEVC,
28 .decode_extension = FF_VK_EXT_VIDEO_DECODE_H265,
29 .queue_flags = VK_QUEUE_VIDEO_DECODE_BIT_KHR,
30 .decode_op = VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_KHR,
31 .ext_props = {
32 .extensionName = VK_STD_VULKAN_VIDEO_CODEC_H265_DECODE_EXTENSION_NAME,
33 .specVersion = VK_STD_VULKAN_VIDEO_CODEC_H265_DECODE_SPEC_VERSION,
34 },
35 };
36
37 typedef struct HEVCHeaderSPS {
38 StdVideoH265ScalingLists scaling;
39 StdVideoH265HrdParameters vui_header;
40 StdVideoH265SequenceParameterSetVui vui;
41 StdVideoH265ProfileTierLevel ptl;
42 StdVideoH265DecPicBufMgr dpbm;
43 StdVideoH265PredictorPaletteEntries pal;
44 StdVideoH265SubLayerHrdParameters nal_hdr[HEVC_MAX_SUB_LAYERS];
45 StdVideoH265SubLayerHrdParameters vcl_hdr[HEVC_MAX_SUB_LAYERS];
46 StdVideoH265ShortTermRefPicSet str[HEVC_MAX_SHORT_TERM_REF_PIC_SETS];
47 StdVideoH265LongTermRefPicsSps ltr;
48 } HEVCHeaderSPS;
49
50 typedef struct HEVCHeaderPPS {
51 StdVideoH265ScalingLists scaling;
52 StdVideoH265PredictorPaletteEntries pal;
53 } HEVCHeaderPPS;
54
55 typedef struct HEVCHeaderVPSSet {
56 StdVideoH265SubLayerHrdParameters nal_hdr[HEVC_MAX_SUB_LAYERS];
57 StdVideoH265SubLayerHrdParameters vcl_hdr[HEVC_MAX_SUB_LAYERS];
58 } HEVCHeaderVPSSet;
59
60 typedef struct HEVCHeaderVPS {
61 StdVideoH265ProfileTierLevel ptl;
62 StdVideoH265DecPicBufMgr dpbm;
63 StdVideoH265HrdParameters hdr[HEVC_MAX_LAYER_SETS];
64 HEVCHeaderVPSSet *sls;
65 } HEVCHeaderVPS;
66
67 typedef struct HEVCHeaderSet {
68 StdVideoH265SequenceParameterSet sps[HEVC_MAX_SPS_COUNT];
69 HEVCHeaderSPS hsps[HEVC_MAX_SPS_COUNT];
70
71 StdVideoH265PictureParameterSet pps[HEVC_MAX_PPS_COUNT];
72 HEVCHeaderPPS hpps[HEVC_MAX_PPS_COUNT];
73
74 StdVideoH265VideoParameterSet vps[HEVC_MAX_PPS_COUNT];
75 HEVCHeaderVPS *hvps;
76 } HEVCHeaderSet;
77
78 ✗ static int alloc_hevc_header_structs(FFVulkanDecodeContext *s,
79 int nb_vps,
80 const int vps_list_idx[HEVC_MAX_VPS_COUNT],
81 const HEVCVPS * const vps_list[HEVC_MAX_VPS_COUNT])
82 {
83 uint8_t *data_ptr;
84 HEVCHeaderSet *hdr;
85
86 ✗ size_t buf_size = sizeof(HEVCHeaderSet) + nb_vps*sizeof(HEVCHeaderVPS);
87
0/2
✗ Branch 4 → 3 not taken.
✗ Branch 4 → 5 not taken.
✗ for (int i = 0; i < nb_vps; i++) {
88 ✗ const HEVCVPS *vps = vps_list[vps_list_idx[i]];
89 ✗ buf_size += sizeof(HEVCHeaderVPSSet)*vps->vps_num_hrd_parameters;
90 }
91
92
0/2
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 11 not taken.
✗ if (buf_size > s->hevc_headers_size) {
93 ✗ av_freep(&s->hevc_headers);
94 ✗ s->hevc_headers_size = 0;
95 ✗ s->hevc_headers = av_mallocz(buf_size);
96
0/2
✗ Branch 8 → 9 not taken.
✗ Branch 8 → 10 not taken.
✗ if (!s->hevc_headers)
97 ✗ return AVERROR(ENOMEM);
98 ✗ s->hevc_headers_size = buf_size;
99 }
100
101 /* Setup struct pointers */
102 ✗ hdr = s->hevc_headers;
103 ✗ data_ptr = (uint8_t *)hdr;
104 ✗ hdr->hvps = (HEVCHeaderVPS *)(data_ptr + sizeof(HEVCHeaderSet));
105 ✗ data_ptr += sizeof(HEVCHeaderSet) + nb_vps*sizeof(HEVCHeaderVPS);
106
0/2
✗ Branch 13 → 12 not taken.
✗ Branch 13 → 14 not taken.
✗ for (int i = 0; i < nb_vps; i++) {
107 ✗ const HEVCVPS *vps = vps_list[vps_list_idx[i]];
108 ✗ hdr->hvps[i].sls = (HEVCHeaderVPSSet *)data_ptr;
109 ✗ data_ptr += sizeof(HEVCHeaderVPSSet)*vps->vps_num_hrd_parameters;
110 }
111
112 ✗ return 0;
113 }
114
115 typedef struct HEVCVulkanDecodePicture {
116 FFVulkanDecodePicture vp;
117
118 /* Current picture */
119 StdVideoDecodeH265ReferenceInfo h265_ref;
120 VkVideoDecodeH265DpbSlotInfoKHR vkh265_ref;
121
122 /* Picture refs */
123 HEVCFrame *ref_src [HEVC_MAX_REFS];
124 StdVideoDecodeH265ReferenceInfo h265_refs [HEVC_MAX_REFS];
125 VkVideoDecodeH265DpbSlotInfoKHR vkh265_refs[HEVC_MAX_REFS];
126
127 /* Current picture (contd.) */
128 StdVideoDecodeH265PictureInfo h265pic;
129 VkVideoDecodeH265PictureInfoKHR h265_pic_info;
130 } HEVCVulkanDecodePicture;
131
132 ✗ static int vk_hevc_fill_pict(AVCodecContext *avctx, HEVCFrame **ref_src,
133 VkVideoReferenceSlotInfoKHR *ref_slot, /* Main structure */
134 VkVideoPictureResourceInfoKHR *ref, /* Goes in ^ */
135 VkVideoDecodeH265DpbSlotInfoKHR *vkh265_ref, /* Goes in ^ */
136 StdVideoDecodeH265ReferenceInfo *h265_ref, /* Goes in ^ */
137 HEVCFrame *pic, int is_current, int pic_id)
138 {
139 ✗ FFVulkanDecodeContext *dec = avctx->internal->hwaccel_priv_data;
140 ✗ FFVulkanDecodeShared *ctx = dec->shared_ctx;
141 ✗ HEVCVulkanDecodePicture *hp = pic->hwaccel_picture_private;
142 ✗ FFVulkanDecodePicture *vkpic = &hp->vp;
143
144 ✗ int err = ff_vk_decode_prepare_frame(dec, pic->f, vkpic, is_current,
145 dec->dedicated_dpb);
146
0/2
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 5 not taken.
✗ if (err < 0)
147 ✗ return err;
148
149 ✗ *h265_ref = (StdVideoDecodeH265ReferenceInfo) {
150 .flags = (StdVideoDecodeH265ReferenceInfoFlags) {
151 .used_for_long_term_reference = pic->flags & HEVC_FRAME_FLAG_LONG_REF,
152 .unused_for_reference = 0,
153 },
154 ✗ .PicOrderCntVal = pic->poc,
155 };
156
157 ✗ *vkh265_ref = (VkVideoDecodeH265DpbSlotInfoKHR) {
158 .sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_DPB_SLOT_INFO_KHR,
159 .pStdReferenceInfo = h265_ref,
160 };
161
162 ✗ *ref = (VkVideoPictureResourceInfoKHR) {
163 .sType = VK_STRUCTURE_TYPE_VIDEO_PICTURE_RESOURCE_INFO_KHR,
164 .codedOffset = (VkOffset2D){ 0, 0 },
165 ✗ .codedExtent = (VkExtent2D){ pic->f->width, pic->f->height },
166
0/2
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 7 not taken.
✗ .baseArrayLayer = ctx->common.layered_dpb ? pic_id : 0,
167 ✗ .imageViewBinding = vkpic->view.ref,
168 };
169
170 ✗ *ref_slot = (VkVideoReferenceSlotInfoKHR) {
171 .sType = VK_STRUCTURE_TYPE_VIDEO_REFERENCE_SLOT_INFO_KHR,
172 .pNext = vkh265_ref,
173 .slotIndex = pic_id,
174 .pPictureResource = ref,
175 };
176
177
0/2
✗ Branch 8 → 9 not taken.
✗ Branch 8 → 10 not taken.
✗ if (ref_src)
178 ✗ *ref_src = pic;
179
180 ✗ return 0;
181 }
182
183 ✗ static void copy_scaling_list(const ScalingList *sl, StdVideoH265ScalingLists *vksl)
184 {
185
0/2
✗ Branch 7 → 3 not taken.
✗ Branch 7 → 8 not taken.
✗ for (int i = 0; i < STD_VIDEO_H265_SCALING_LIST_4X4_NUM_LISTS; i++) {
186
0/2
✗ Branch 5 → 4 not taken.
✗ Branch 5 → 6 not taken.
✗ for (int j = 0; j < STD_VIDEO_H265_SCALING_LIST_4X4_NUM_ELEMENTS; j++) {
187 ✗ uint8_t pos = 4 * ff_hevc_diag_scan4x4_y[j] + ff_hevc_diag_scan4x4_x[j];
188 ✗ vksl->ScalingList4x4[i][j] = sl->sl[0][i][pos];
189 }
190 }
191
192
0/2
✗ Branch 13 → 9 not taken.
✗ Branch 13 → 14 not taken.
✗ for (int i = 0; i < STD_VIDEO_H265_SCALING_LIST_8X8_NUM_LISTS; i++) {
193
0/2
✗ Branch 11 → 10 not taken.
✗ Branch 11 → 12 not taken.
✗ for (int j = 0; j < STD_VIDEO_H265_SCALING_LIST_8X8_NUM_ELEMENTS; j++) {
194 ✗ uint8_t pos = 8 * ff_hevc_diag_scan8x8_y[j] + ff_hevc_diag_scan8x8_x[j];
195 ✗ vksl->ScalingList8x8[i][j] = sl->sl[1][i][pos];
196 }
197 }
198
199
0/2
✗ Branch 19 → 15 not taken.
✗ Branch 19 → 20 not taken.
✗ for (int i = 0; i < STD_VIDEO_H265_SCALING_LIST_16X16_NUM_LISTS; i++) {
200
0/2
✗ Branch 17 → 16 not taken.
✗ Branch 17 → 18 not taken.
✗ for (int j = 0; j < STD_VIDEO_H265_SCALING_LIST_16X16_NUM_ELEMENTS; j++) {
201 ✗ uint8_t pos = 8 * ff_hevc_diag_scan8x8_y[j] + ff_hevc_diag_scan8x8_x[j];
202 ✗ vksl->ScalingList16x16[i][j] = sl->sl[2][i][pos];
203 }
204 }
205
206
0/2
✗ Branch 25 → 21 not taken.
✗ Branch 25 → 26 not taken.
✗ for (int i = 0; i < STD_VIDEO_H265_SCALING_LIST_32X32_NUM_LISTS; i++) {
207
0/2
✗ Branch 23 → 22 not taken.
✗ Branch 23 → 24 not taken.
✗ for (int j = 0; j < STD_VIDEO_H265_SCALING_LIST_32X32_NUM_ELEMENTS; j++) {
208 ✗ uint8_t pos = 8 * ff_hevc_diag_scan8x8_y[j] + ff_hevc_diag_scan8x8_x[j];
209 ✗ vksl->ScalingList32x32[i][j] = sl->sl[3][i * 3][pos];
210 }
211 }
212
213 ✗ memcpy(vksl->ScalingListDCCoef16x16, sl->sl_dc[0],
214 STD_VIDEO_H265_SCALING_LIST_16X16_NUM_LISTS * sizeof(*vksl->ScalingListDCCoef16x16));
215
216
0/2
✗ Branch 28 → 27 not taken.
✗ Branch 28 → 29 not taken.
✗ for (int i = 0; i < STD_VIDEO_H265_SCALING_LIST_32X32_NUM_LISTS; i++)
217 ✗ vksl->ScalingListDCCoef32x32[i] = sl->sl_dc[1][i * 3];
218 ✗ }
219
220 ✗ static void set_sps(const HEVCSPS *sps, int sps_idx,
221 StdVideoH265ScalingLists *vksps_scaling,
222 StdVideoH265HrdParameters *vksps_vui_header,
223 StdVideoH265SequenceParameterSetVui *vksps_vui,
224 StdVideoH265SequenceParameterSet *vksps,
225 StdVideoH265SubLayerHrdParameters *slhdrnal,
226 StdVideoH265SubLayerHrdParameters *slhdrvcl,
227 StdVideoH265ProfileTierLevel *ptl,
228 StdVideoH265DecPicBufMgr *dpbm,
229 StdVideoH265PredictorPaletteEntries *pal,
230 StdVideoH265ShortTermRefPicSet *str,
231 StdVideoH265LongTermRefPicsSps *ltr)
232 {
233 ✗ copy_scaling_list(&sps->scaling_list, vksps_scaling);
234
235 ✗ *vksps_vui_header = (StdVideoH265HrdParameters) {
236 .flags = (StdVideoH265HrdFlags) {
237 ✗ .nal_hrd_parameters_present_flag = sps->hdr.nal_hrd_parameters_present_flag,
238 ✗ .vcl_hrd_parameters_present_flag = sps->hdr.vcl_hrd_parameters_present_flag,
239 ✗ .sub_pic_hrd_params_present_flag = sps->hdr.sub_pic_hrd_params_present_flag,
240 ✗ .sub_pic_cpb_params_in_pic_timing_sei_flag = sps->hdr.sub_pic_cpb_params_in_pic_timing_sei_flag,
241 ✗ .fixed_pic_rate_general_flag = sps->hdr.flags.fixed_pic_rate_general_flag,
242 ✗ .fixed_pic_rate_within_cvs_flag = sps->hdr.flags.fixed_pic_rate_within_cvs_flag,
243 ✗ .low_delay_hrd_flag = sps->hdr.flags.low_delay_hrd_flag,
244 },
245 ✗ .tick_divisor_minus2 = sps->hdr.tick_divisor_minus2,
246 ✗ .du_cpb_removal_delay_increment_length_minus1 = sps->hdr.du_cpb_removal_delay_increment_length_minus1,
247 ✗ .dpb_output_delay_du_length_minus1 = sps->hdr.dpb_output_delay_du_length_minus1,
248 ✗ .bit_rate_scale = sps->hdr.bit_rate_scale,
249 ✗ .cpb_size_scale = sps->hdr.cpb_size_scale,
250 ✗ .cpb_size_du_scale = sps->hdr.cpb_size_du_scale,
251 ✗ .initial_cpb_removal_delay_length_minus1 = sps->hdr.initial_cpb_removal_delay_length_minus1,
252 ✗ .au_cpb_removal_delay_length_minus1 = sps->hdr.au_cpb_removal_delay_length_minus1,
253 ✗ .dpb_output_delay_length_minus1 = sps->hdr.dpb_output_delay_length_minus1,
254 /* Reserved - 3*16 bits */
255 .pSubLayerHrdParametersNal = slhdrnal,
256 .pSubLayerHrdParametersVcl = slhdrvcl,
257 };
258
259 ✗ memcpy(vksps_vui_header->cpb_cnt_minus1, sps->hdr.cpb_cnt_minus1,
260 STD_VIDEO_H265_SUBLAYERS_LIST_SIZE*sizeof(*vksps_vui_header->cpb_cnt_minus1));
261 ✗ memcpy(vksps_vui_header->elemental_duration_in_tc_minus1, sps->hdr.elemental_duration_in_tc_minus1,
262 STD_VIDEO_H265_SUBLAYERS_LIST_SIZE*sizeof(*vksps_vui_header->elemental_duration_in_tc_minus1));
263
264 ✗ memcpy(slhdrnal, sps->hdr.nal_params, HEVC_MAX_SUB_LAYERS*sizeof(*slhdrnal));
265 ✗ memcpy(slhdrvcl, sps->hdr.vcl_params, HEVC_MAX_SUB_LAYERS*sizeof(*slhdrvcl));
266
267 ✗ *vksps_vui = (StdVideoH265SequenceParameterSetVui) {
268 .flags = (StdVideoH265SpsVuiFlags) {
269 ✗ .aspect_ratio_info_present_flag = sps->vui.common.aspect_ratio_info_present_flag,
270 ✗ .overscan_info_present_flag = sps->vui.common.overscan_info_present_flag,
271 ✗ .overscan_appropriate_flag = sps->vui.common.overscan_appropriate_flag,
272 ✗ .video_signal_type_present_flag = sps->vui.common.video_signal_type_present_flag,
273 ✗ .video_full_range_flag = sps->vui.common.video_full_range_flag,
274 ✗ .colour_description_present_flag = sps->vui.common.colour_description_present_flag,
275 ✗ .chroma_loc_info_present_flag = sps->vui.common.chroma_loc_info_present_flag,
276 ✗ .neutral_chroma_indication_flag = sps->vui.neutra_chroma_indication_flag,
277 ✗ .field_seq_flag = sps->vui.field_seq_flag,
278 ✗ .frame_field_info_present_flag = sps->vui.frame_field_info_present_flag,
279 ✗ .default_display_window_flag = sps->vui.default_display_window_flag,
280 ✗ .vui_timing_info_present_flag = sps->vui.vui_timing_info_present_flag,
281 ✗ .vui_poc_proportional_to_timing_flag = sps->vui.vui_poc_proportional_to_timing_flag,
282 ✗ .vui_hrd_parameters_present_flag = sps->vui.vui_hrd_parameters_present_flag,
283 ✗ .bitstream_restriction_flag = sps->vui.bitstream_restriction_flag,
284 ✗ .tiles_fixed_structure_flag = sps->vui.tiles_fixed_structure_flag,
285 ✗ .motion_vectors_over_pic_boundaries_flag = sps->vui.motion_vectors_over_pic_boundaries_flag,
286 ✗ .restricted_ref_pic_lists_flag = sps->vui.restricted_ref_pic_lists_flag,
287 },
288 ✗ .aspect_ratio_idc = sps->vui.common.aspect_ratio_idc,
289 ✗ .sar_width = sps->vui.common.sar.num,
290 ✗ .sar_height = sps->vui.common.sar.den,
291 ✗ .video_format = sps->vui.common.video_format,
292 ✗ .colour_primaries = sps->vui.common.colour_primaries,
293 ✗ .transfer_characteristics = sps->vui.common.transfer_characteristics,
294 ✗ .matrix_coeffs = sps->vui.common.matrix_coeffs,
295 ✗ .chroma_sample_loc_type_top_field = sps->vui.common.chroma_sample_loc_type_top_field,
296 ✗ .chroma_sample_loc_type_bottom_field = sps->vui.common.chroma_sample_loc_type_bottom_field,
297 /* Reserved */
298 /* Reserved */
299 ✗ .def_disp_win_left_offset = sps->vui.def_disp_win.left_offset,
300 ✗ .def_disp_win_right_offset = sps->vui.def_disp_win.right_offset,
301 ✗ .def_disp_win_top_offset = sps->vui.def_disp_win.top_offset,
302 ✗ .def_disp_win_bottom_offset = sps->vui.def_disp_win.bottom_offset,
303 ✗ .vui_num_units_in_tick = sps->vui.vui_num_units_in_tick,
304 ✗ .vui_time_scale = sps->vui.vui_time_scale,
305 ✗ .vui_num_ticks_poc_diff_one_minus1 = sps->vui.vui_num_ticks_poc_diff_one_minus1,
306 ✗ .min_spatial_segmentation_idc = sps->vui.min_spatial_segmentation_idc,
307 ✗ .max_bytes_per_pic_denom = sps->vui.max_bytes_per_pic_denom,
308 ✗ .max_bits_per_min_cu_denom = sps->vui.max_bits_per_min_cu_denom,
309 ✗ .log2_max_mv_length_horizontal = sps->vui.log2_max_mv_length_horizontal,
310 ✗ .log2_max_mv_length_vertical = sps->vui.log2_max_mv_length_vertical,
311 .pHrdParameters = vksps_vui_header,
312 };
313
314 ✗ *ptl = (StdVideoH265ProfileTierLevel) {
315 .flags = (StdVideoH265ProfileTierLevelFlags) {
316 ✗ .general_tier_flag = sps->ptl.general_ptl.tier_flag,
317 ✗ .general_progressive_source_flag = sps->ptl.general_ptl.progressive_source_flag,
318 ✗ .general_interlaced_source_flag = sps->ptl.general_ptl.interlaced_source_flag,
319 ✗ .general_non_packed_constraint_flag = sps->ptl.general_ptl.non_packed_constraint_flag,
320 ✗ .general_frame_only_constraint_flag = sps->ptl.general_ptl.frame_only_constraint_flag,
321 },
322 ✗ .general_profile_idc = sps->ptl.general_ptl.profile_idc,
323 ✗ .general_level_idc = ff_vk_h265_level_to_vk(sps->ptl.general_ptl.level_idc),
324 };
325
326
0/2
✗ Branch 6 → 5 not taken.
✗ Branch 6 → 7 not taken.
✗ for (int i = 0; i < sps->max_sub_layers; i++) {
327 ✗ dpbm->max_latency_increase_plus1[i] = sps->temporal_layer[i].max_latency_increase + 1;
328 ✗ dpbm->max_dec_pic_buffering_minus1[i] = sps->temporal_layer[i].max_dec_pic_buffering - 1;
329 ✗ dpbm->max_num_reorder_pics[i] = sps->temporal_layer[i].num_reorder_pics;
330 }
331
332
0/4
✗ Branch 12 → 13 not taken.
✗ Branch 12 → 14 not taken.
✗ Branch 15 → 8 not taken.
✗ Branch 15 → 16 not taken.
✗ for (int i = 0; i < (sps->chroma_format_idc ? 3 : 1); i++)
333
0/2
✗ Branch 10 → 9 not taken.
✗ Branch 10 → 11 not taken.
✗ for (int j = 0; j < sps->sps_num_palette_predictor_initializers; j++)
334 ✗ pal->PredictorPaletteEntries[i][j] = sps->sps_palette_predictor_initializer[i][j];
335
336
0/2
✗ Branch 30 → 17 not taken.
✗ Branch 30 → 31 not taken.
✗ for (int i = 0; i < sps->nb_st_rps; i++) {
337 ✗ const ShortTermRPS *st_rps = &sps->st_rps[i];
338
339 ✗ str[i] = (StdVideoH265ShortTermRefPicSet) {
340 .flags = (StdVideoH265ShortTermRefPicSetFlags) {
341 ✗ .inter_ref_pic_set_prediction_flag = sps->st_rps[i].rps_predict,
342 ✗ .delta_rps_sign = sps->st_rps[i].delta_rps_sign,
343 },
344 ✗ .delta_idx_minus1 = sps->st_rps[i].delta_idx - 1,
345 ✗ .use_delta_flag = sps->st_rps[i].use_delta,
346 ✗ .abs_delta_rps_minus1 = sps->st_rps[i].abs_delta_rps - 1,
347 .used_by_curr_pic_flag = 0x0,
348 .used_by_curr_pic_s0_flag = 0x0,
349 .used_by_curr_pic_s1_flag = 0x0,
350 /* Reserved */
351 /* Reserved */
352 /* Reserved */
353 ✗ .num_negative_pics = sps->st_rps[i].num_negative_pics,
354 ✗ .num_positive_pics = sps->st_rps[i].num_delta_pocs - sps->st_rps[i].num_negative_pics,
355 };
356
357 /* NOTE: This is the predicted, and *reordered* version.
358 * Probably incorrect, but the spec doesn't say which version to use. */
359 ✗ str[i].used_by_curr_pic_flag = st_rps->used;
360 ✗ str[i].used_by_curr_pic_s0_flag = av_zero_extend(st_rps->used, str[i].num_negative_pics);
361 ✗ str[i].used_by_curr_pic_s1_flag = st_rps->used >> str[i].num_negative_pics;
362
363
0/2
✗ Branch 22 → 18 not taken.
✗ Branch 22 → 23 not taken.
✗ for (int j = 0; j < str[i].num_negative_pics; j++)
364
0/2
✗ Branch 18 → 19 not taken.
✗ Branch 18 → 20 not taken.
✗ str[i].delta_poc_s0_minus1[j] = st_rps->delta_poc[j] - (j ? st_rps->delta_poc[j - 1] : 0) - 1;
365
366
0/2
✗ Branch 28 → 24 not taken.
✗ Branch 28 → 29 not taken.
✗ for (int j = 0; j < str[i].num_positive_pics; j++)
367
0/2
✗ Branch 24 → 25 not taken.
✗ Branch 24 → 26 not taken.
✗ str[i].delta_poc_s1_minus1[j] = st_rps->delta_poc[st_rps->num_negative_pics + j] -
368 ✗ (j ? st_rps->delta_poc[st_rps->num_negative_pics + j - 1] : 0) - 1;
369 }
370
371 ✗ *ltr = (StdVideoH265LongTermRefPicsSps) {
372 ✗ .used_by_curr_pic_lt_sps_flag = sps->used_by_curr_pic_lt,
373 };
374
375
0/2
✗ Branch 33 → 32 not taken.
✗ Branch 33 → 34 not taken.
✗ for (int i = 0; i < sps->num_long_term_ref_pics_sps; i++) {
376 ✗ ltr->lt_ref_pic_poc_lsb_sps[i] = sps->lt_ref_pic_poc_lsb_sps[i];
377 }
378
379 ✗ *vksps = (StdVideoH265SequenceParameterSet) {
380 .flags = (StdVideoH265SpsFlags) {
381 ✗ .sps_temporal_id_nesting_flag = sps->temporal_id_nesting,
382 ✗ .separate_colour_plane_flag = sps->separate_colour_plane,
383 ✗ .conformance_window_flag = sps->conformance_window,
384 ✗ .sps_sub_layer_ordering_info_present_flag = sps->sublayer_ordering_info,
385 ✗ .scaling_list_enabled_flag = sps->scaling_list_enabled,
386 ✗ .sps_scaling_list_data_present_flag = sps->scaling_list_enabled,
387 ✗ .amp_enabled_flag = sps->amp_enabled,
388 ✗ .sample_adaptive_offset_enabled_flag = sps->sao_enabled,
389 ✗ .pcm_enabled_flag = sps->pcm_enabled,
390 ✗ .pcm_loop_filter_disabled_flag = sps->pcm_loop_filter_disabled,
391 ✗ .long_term_ref_pics_present_flag = sps->long_term_ref_pics_present,
392 ✗ .sps_temporal_mvp_enabled_flag = sps->temporal_mvp_enabled,
393 ✗ .strong_intra_smoothing_enabled_flag = sps->strong_intra_smoothing_enabled,
394 ✗ .vui_parameters_present_flag = sps->vui_present,
395 ✗ .sps_extension_present_flag = sps->extension_present,
396 ✗ .sps_range_extension_flag = sps->range_extension,
397 ✗ .transform_skip_rotation_enabled_flag = sps->transform_skip_rotation_enabled,
398 ✗ .transform_skip_context_enabled_flag = sps->transform_skip_context_enabled,
399 ✗ .implicit_rdpcm_enabled_flag = sps->implicit_rdpcm_enabled,
400 ✗ .explicit_rdpcm_enabled_flag = sps->explicit_rdpcm_enabled,
401 ✗ .extended_precision_processing_flag = sps->extended_precision_processing,
402 ✗ .intra_smoothing_disabled_flag = sps->intra_smoothing_disabled,
403 ✗ .high_precision_offsets_enabled_flag = sps->high_precision_offsets_enabled,
404 ✗ .persistent_rice_adaptation_enabled_flag = sps->persistent_rice_adaptation_enabled,
405 ✗ .cabac_bypass_alignment_enabled_flag = sps->cabac_bypass_alignment_enabled,
406 ✗ .sps_scc_extension_flag = sps->scc_extension,
407 ✗ .sps_curr_pic_ref_enabled_flag = sps->curr_pic_ref_enabled,
408 ✗ .palette_mode_enabled_flag = sps->palette_mode_enabled,
409 ✗ .sps_palette_predictor_initializers_present_flag = sps->palette_predictor_initializers_present,
410 ✗ .intra_boundary_filtering_disabled_flag = sps->intra_boundary_filtering_disabled,
411 },
412 ✗ .chroma_format_idc = sps->chroma_format_idc,
413 ✗ .pic_width_in_luma_samples = sps->width,
414 ✗ .pic_height_in_luma_samples = sps->height,
415 ✗ .sps_video_parameter_set_id = sps->vps_id,
416 ✗ .sps_max_sub_layers_minus1 = sps->max_sub_layers - 1,
417 .sps_seq_parameter_set_id = sps_idx,
418 ✗ .bit_depth_luma_minus8 = sps->bit_depth - 8,
419 ✗ .bit_depth_chroma_minus8 = sps->bit_depth_chroma - 8,
420 ✗ .log2_max_pic_order_cnt_lsb_minus4 = sps->log2_max_poc_lsb - 4,
421 ✗ .log2_min_luma_coding_block_size_minus3 = sps->log2_min_cb_size - 3,
422 ✗ .log2_diff_max_min_luma_coding_block_size = sps->log2_diff_max_min_coding_block_size,
423 ✗ .log2_min_luma_transform_block_size_minus2 = sps->log2_min_tb_size - 2,
424 ✗ .log2_diff_max_min_luma_transform_block_size = sps->log2_diff_max_min_transform_block_size,
425 ✗ .max_transform_hierarchy_depth_inter = sps->max_transform_hierarchy_depth_inter,
426 ✗ .max_transform_hierarchy_depth_intra = sps->max_transform_hierarchy_depth_intra,
427 ✗ .num_short_term_ref_pic_sets = sps->nb_st_rps,
428 ✗ .num_long_term_ref_pics_sps = sps->num_long_term_ref_pics_sps,
429 ✗ .pcm_sample_bit_depth_luma_minus1 = sps->pcm.bit_depth - 1,
430 ✗ .pcm_sample_bit_depth_chroma_minus1 = sps->pcm.bit_depth_chroma - 1,
431 ✗ .log2_min_pcm_luma_coding_block_size_minus3 = sps->pcm.log2_min_pcm_cb_size - 3,
432 ✗ .log2_diff_max_min_pcm_luma_coding_block_size = sps->pcm.log2_max_pcm_cb_size - sps->pcm.log2_min_pcm_cb_size,
433 /* Reserved */
434 /* Reserved */
435 ✗ .palette_max_size = sps->palette_max_size,
436 ✗ .delta_palette_max_predictor_size = sps->delta_palette_max_predictor_size,
437 ✗ .motion_vector_resolution_control_idc = sps->motion_vector_resolution_control_idc,
438 ✗ .sps_num_palette_predictor_initializers_minus1 = sps->sps_num_palette_predictor_initializers - 1,
439 ✗ .conf_win_left_offset = sps->pic_conf_win.left_offset,
440 ✗ .conf_win_right_offset = sps->pic_conf_win.right_offset,
441 ✗ .conf_win_top_offset = sps->pic_conf_win.top_offset,
442 ✗ .conf_win_bottom_offset = sps->pic_conf_win.bottom_offset,
443 .pProfileTierLevel = ptl,
444 .pDecPicBufMgr = dpbm,
445 .pScalingLists = vksps_scaling,
446 .pShortTermRefPicSet = str,
447 .pLongTermRefPicsSps = ltr,
448 .pSequenceParameterSetVui = vksps_vui,
449 .pPredictorPaletteEntries = pal,
450 };
451 ✗ }
452
453 ✗ static void set_pps(const HEVCPPS *pps, const HEVCSPS *sps,
454 StdVideoH265ScalingLists *vkpps_scaling,
455 StdVideoH265PictureParameterSet *vkpps,
456 StdVideoH265PredictorPaletteEntries *pal)
457 {
458 ✗ copy_scaling_list(&pps->scaling_list, vkpps_scaling);
459
460 ✗ *vkpps = (StdVideoH265PictureParameterSet) {
461 .flags = (StdVideoH265PpsFlags) {
462 ✗ .dependent_slice_segments_enabled_flag = pps->dependent_slice_segments_enabled_flag,
463 ✗ .output_flag_present_flag = pps->output_flag_present_flag,
464 ✗ .sign_data_hiding_enabled_flag = pps->sign_data_hiding_flag,
465 ✗ .cabac_init_present_flag = pps->cabac_init_present_flag,
466 ✗ .constrained_intra_pred_flag = pps->constrained_intra_pred_flag,
467 ✗ .transform_skip_enabled_flag = pps->transform_skip_enabled_flag,
468 ✗ .cu_qp_delta_enabled_flag = pps->cu_qp_delta_enabled_flag,
469 ✗ .pps_slice_chroma_qp_offsets_present_flag = pps->pic_slice_level_chroma_qp_offsets_present_flag,
470 ✗ .weighted_pred_flag = pps->weighted_pred_flag,
471 ✗ .weighted_bipred_flag = pps->weighted_bipred_flag,
472 ✗ .transquant_bypass_enabled_flag = pps->transquant_bypass_enable_flag,
473 ✗ .tiles_enabled_flag = pps->tiles_enabled_flag,
474 ✗ .entropy_coding_sync_enabled_flag = pps->entropy_coding_sync_enabled_flag,
475 ✗ .uniform_spacing_flag = pps->uniform_spacing_flag,
476 ✗ .loop_filter_across_tiles_enabled_flag = pps->loop_filter_across_tiles_enabled_flag,
477 ✗ .pps_loop_filter_across_slices_enabled_flag = pps->seq_loop_filter_across_slices_enabled_flag,
478 ✗ .deblocking_filter_control_present_flag = pps->deblocking_filter_control_present_flag,
479 ✗ .deblocking_filter_override_enabled_flag = pps->deblocking_filter_override_enabled_flag,
480 ✗ .pps_deblocking_filter_disabled_flag = pps->disable_dbf,
481 ✗ .pps_scaling_list_data_present_flag = pps->scaling_list_data_present_flag,
482 ✗ .lists_modification_present_flag = pps->lists_modification_present_flag,
483 ✗ .slice_segment_header_extension_present_flag = pps->slice_header_extension_present_flag,
484 ✗ .pps_extension_present_flag = pps->pps_extension_present_flag,
485 ✗ .cross_component_prediction_enabled_flag = pps->cross_component_prediction_enabled_flag,
486 ✗ .chroma_qp_offset_list_enabled_flag = pps->chroma_qp_offset_list_enabled_flag,
487 ✗ .pps_curr_pic_ref_enabled_flag = pps->pps_curr_pic_ref_enabled_flag,
488 ✗ .residual_adaptive_colour_transform_enabled_flag = pps->residual_adaptive_colour_transform_enabled_flag,
489 ✗ .pps_slice_act_qp_offsets_present_flag = pps->pps_slice_act_qp_offsets_present_flag,
490 ✗ .pps_palette_predictor_initializers_present_flag = pps->pps_palette_predictor_initializers_present_flag,
491 ✗ .monochrome_palette_flag = pps->monochrome_palette_flag,
492 ✗ .pps_range_extension_flag = pps->pps_range_extensions_flag,
493 },
494 ✗ .pps_pic_parameter_set_id = pps->pps_id,
495 ✗ .pps_seq_parameter_set_id = pps->sps_id,
496 ✗ .sps_video_parameter_set_id = sps->vps_id,
497 ✗ .num_extra_slice_header_bits = pps->num_extra_slice_header_bits,
498 ✗ .num_ref_idx_l0_default_active_minus1 = pps->num_ref_idx_l0_default_active - 1,
499 ✗ .num_ref_idx_l1_default_active_minus1 = pps->num_ref_idx_l1_default_active - 1,
500 ✗ .init_qp_minus26 = pps->pic_init_qp_minus26,
501 ✗ .diff_cu_qp_delta_depth = pps->diff_cu_qp_delta_depth,
502 ✗ .pps_cb_qp_offset = pps->cb_qp_offset,
503 ✗ .pps_cr_qp_offset = pps->cr_qp_offset,
504 ✗ .pps_beta_offset_div2 = pps->beta_offset >> 1,
505 ✗ .pps_tc_offset_div2 = pps->tc_offset >> 1,
506 ✗ .log2_parallel_merge_level_minus2 = pps->log2_parallel_merge_level - 2,
507 ✗ .log2_max_transform_skip_block_size_minus2 = pps->log2_max_transform_skip_block_size - 2,
508 ✗ .diff_cu_chroma_qp_offset_depth = pps->diff_cu_chroma_qp_offset_depth,
509 ✗ .chroma_qp_offset_list_len_minus1 = pps->chroma_qp_offset_list_len_minus1,
510 ✗ .log2_sao_offset_scale_luma = pps->log2_sao_offset_scale_luma,
511 ✗ .log2_sao_offset_scale_chroma = pps->log2_sao_offset_scale_chroma,
512 ✗ .pps_act_y_qp_offset_plus5 = pps->pps_act_y_qp_offset + 5,
513 ✗ .pps_act_cb_qp_offset_plus5 = pps->pps_act_cb_qp_offset + 5,
514 ✗ .pps_act_cr_qp_offset_plus3 = pps->pps_act_cr_qp_offset + 3,
515 ✗ .pps_num_palette_predictor_initializers = pps->pps_num_palette_predictor_initializers,
516 ✗ .luma_bit_depth_entry_minus8 = pps->luma_bit_depth_entry - 8,
517 ✗ .chroma_bit_depth_entry_minus8 = pps->chroma_bit_depth_entry - 8,
518 ✗ .num_tile_columns_minus1 = pps->num_tile_columns - 1,
519 ✗ .num_tile_rows_minus1 = pps->num_tile_rows - 1,
520 .pScalingLists = vkpps_scaling,
521 .pPredictorPaletteEntries = pal,
522 };
523
524
0/4
✗ Branch 8 → 9 not taken.
✗ Branch 8 → 10 not taken.
✗ Branch 11 → 4 not taken.
✗ Branch 11 → 12 not taken.
✗ for (int i = 0; i < (pps->monochrome_palette_flag ? 1 : 3); i++) {
525
0/2
✗ Branch 6 → 5 not taken.
✗ Branch 6 → 7 not taken.
✗ for (int j = 0; j < pps->pps_num_palette_predictor_initializers; j++)
526 ✗ pal->PredictorPaletteEntries[i][j] = pps->pps_palette_predictor_initializer[i][j];
527 }
528
529
0/2
✗ Branch 14 → 13 not taken.
✗ Branch 14 → 15 not taken.
✗ for (int i = 0; i < pps->num_tile_columns - 1; i++)
530 ✗ vkpps->column_width_minus1[i] = pps->column_width[i] - 1;
531
532
0/2
✗ Branch 17 → 16 not taken.
✗ Branch 17 → 18 not taken.
✗ for (int i = 0; i < pps->num_tile_rows - 1; i++)
533 ✗ vkpps->row_height_minus1[i] = pps->row_height[i] - 1;
534
535
0/2
✗ Branch 20 → 19 not taken.
✗ Branch 20 → 21 not taken.
✗ for (int i = 0; i <= pps->chroma_qp_offset_list_len_minus1; i++) {
536 ✗ vkpps->cb_qp_offset_list[i] = pps->cb_qp_offset_list[i];
537 ✗ vkpps->cr_qp_offset_list[i] = pps->cr_qp_offset_list[i];
538 }
539 ✗ }
540
541 ✗ static void set_vps(const HEVCVPS *vps,
542 StdVideoH265VideoParameterSet *vkvps,
543 StdVideoH265ProfileTierLevel *ptl,
544 StdVideoH265DecPicBufMgr *dpbm,
545 StdVideoH265HrdParameters *sls_hdr,
546 HEVCHeaderVPSSet sls[])
547 {
548
0/2
✗ Branch 4 → 3 not taken.
✗ Branch 4 → 5 not taken.
✗ for (int i = 0; i < vps->vps_num_hrd_parameters; i++) {
549 ✗ const HEVCHdrParams *src = &vps->hdr[i];
550
551 ✗ sls_hdr[i] = (StdVideoH265HrdParameters) {
552 .flags = (StdVideoH265HrdFlags) {
553 ✗ .nal_hrd_parameters_present_flag = src->nal_hrd_parameters_present_flag,
554 ✗ .vcl_hrd_parameters_present_flag = src->vcl_hrd_parameters_present_flag,
555 ✗ .sub_pic_hrd_params_present_flag = src->sub_pic_hrd_params_present_flag,
556 ✗ .sub_pic_cpb_params_in_pic_timing_sei_flag = src->sub_pic_cpb_params_in_pic_timing_sei_flag,
557 ✗ .fixed_pic_rate_general_flag = src->flags.fixed_pic_rate_general_flag,
558 ✗ .fixed_pic_rate_within_cvs_flag = src->flags.fixed_pic_rate_within_cvs_flag,
559 ✗ .low_delay_hrd_flag = src->flags.low_delay_hrd_flag,
560 },
561 ✗ .tick_divisor_minus2 = src->tick_divisor_minus2,
562 ✗ .du_cpb_removal_delay_increment_length_minus1 = src->du_cpb_removal_delay_increment_length_minus1,
563 ✗ .dpb_output_delay_du_length_minus1 = src->dpb_output_delay_du_length_minus1,
564 ✗ .bit_rate_scale = src->bit_rate_scale,
565 ✗ .cpb_size_scale = src->cpb_size_scale,
566 ✗ .cpb_size_du_scale = src->cpb_size_du_scale,
567 ✗ .initial_cpb_removal_delay_length_minus1 = src->initial_cpb_removal_delay_length_minus1,
568 ✗ .au_cpb_removal_delay_length_minus1 = src->au_cpb_removal_delay_length_minus1,
569 ✗ .dpb_output_delay_length_minus1 = src->dpb_output_delay_length_minus1,
570 /* Reserved - 3*16 bits */
571 ✗ .pSubLayerHrdParametersNal = sls[i].nal_hdr,
572 ✗ .pSubLayerHrdParametersVcl = sls[i].vcl_hdr,
573 };
574
575 ✗ memcpy(sls_hdr[i].cpb_cnt_minus1, src->cpb_cnt_minus1,
576 STD_VIDEO_H265_SUBLAYERS_LIST_SIZE*sizeof(*sls_hdr[i].cpb_cnt_minus1));
577 ✗ memcpy(sls_hdr[i].elemental_duration_in_tc_minus1, src->elemental_duration_in_tc_minus1,
578 STD_VIDEO_H265_SUBLAYERS_LIST_SIZE*sizeof(*sls_hdr[i].elemental_duration_in_tc_minus1));
579
580 ✗ memcpy(sls[i].nal_hdr, src->nal_params, HEVC_MAX_SUB_LAYERS*sizeof(*sls[i].nal_hdr));
581 ✗ memcpy(sls[i].vcl_hdr, src->vcl_params, HEVC_MAX_SUB_LAYERS*sizeof(*sls[i].vcl_hdr));
582 }
583
584 ✗ *ptl = (StdVideoH265ProfileTierLevel) {
585 .flags = (StdVideoH265ProfileTierLevelFlags) {
586 ✗ .general_tier_flag = vps->ptl.general_ptl.tier_flag,
587 ✗ .general_progressive_source_flag = vps->ptl.general_ptl.progressive_source_flag,
588 ✗ .general_interlaced_source_flag = vps->ptl.general_ptl.interlaced_source_flag,
589 ✗ .general_non_packed_constraint_flag = vps->ptl.general_ptl.non_packed_constraint_flag,
590 ✗ .general_frame_only_constraint_flag = vps->ptl.general_ptl.frame_only_constraint_flag,
591 },
592 ✗ .general_profile_idc = ff_vk_h265_profile_to_vk(vps->ptl.general_ptl.profile_idc),
593 ✗ .general_level_idc = ff_vk_h265_level_to_vk(vps->ptl.general_ptl.level_idc),
594 };
595
596
0/2
✗ Branch 9 → 8 not taken.
✗ Branch 9 → 10 not taken.
✗ for (int i = 0; i < vps->vps_max_sub_layers; i++) {
597 ✗ dpbm->max_latency_increase_plus1[i] = vps->vps_max_latency_increase[i] + 1;
598 ✗ dpbm->max_dec_pic_buffering_minus1[i] = vps->vps_max_dec_pic_buffering[i] - 1;
599 ✗ dpbm->max_num_reorder_pics[i] = vps->vps_num_reorder_pics[i];
600 }
601
602 ✗ *vkvps = (StdVideoH265VideoParameterSet) {
603 .flags = (StdVideoH265VpsFlags) {
604 ✗ .vps_temporal_id_nesting_flag = vps->vps_temporal_id_nesting_flag,
605 ✗ .vps_sub_layer_ordering_info_present_flag = vps->vps_sub_layer_ordering_info_present_flag,
606 ✗ .vps_timing_info_present_flag = vps->vps_timing_info_present_flag,
607 ✗ .vps_poc_proportional_to_timing_flag = vps->vps_poc_proportional_to_timing_flag,
608 },
609 ✗ .vps_video_parameter_set_id = vps->vps_id,
610 ✗ .vps_max_sub_layers_minus1 = vps->vps_max_sub_layers - 1,
611 /* Reserved */
612 /* Reserved */
613 ✗ .vps_num_units_in_tick = vps->vps_num_units_in_tick,
614 ✗ .vps_time_scale = vps->vps_time_scale,
615 ✗ .vps_num_ticks_poc_diff_one_minus1 = vps->vps_num_ticks_poc_diff_one - 1,
616 /* Reserved */
617 .pDecPicBufMgr = dpbm,
618 .pHrdParameters = sls_hdr,
619 .pProfileTierLevel = ptl,
620 };
621 ✗ }
622
623 ✗ static int vk_hevc_create_params(AVCodecContext *avctx, VkVideoSessionParametersKHR **buf)
624 {
625 int err;
626 ✗ const HEVCContext *h = avctx->priv_data;
627 ✗ FFVulkanDecodeContext *dec = avctx->internal->hwaccel_priv_data;
628 ✗ FFVulkanDecodeShared *ctx = dec->shared_ctx;
629
630 ✗ VkVideoDecodeH265SessionParametersAddInfoKHR h265_params_info = {
631 .sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_SESSION_PARAMETERS_ADD_INFO_KHR,
632 .stdSPSCount = 0,
633 .stdPPSCount = 0,
634 .stdVPSCount = 0,
635 };
636 ✗ VkVideoDecodeH265SessionParametersCreateInfoKHR h265_params = {
637 .sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_SESSION_PARAMETERS_CREATE_INFO_KHR,
638 .pParametersAddInfo = &h265_params_info,
639 };
640 ✗ VkVideoSessionParametersCreateInfoKHR session_params_create = {
641 .sType = VK_STRUCTURE_TYPE_VIDEO_SESSION_PARAMETERS_CREATE_INFO_KHR,
642 .pNext = &h265_params,
643 ✗ .videoSession = ctx->common.session,
644 .videoSessionParametersTemplate = VK_NULL_HANDLE,
645 };
646
647 HEVCHeaderSet *hdr;
648 ✗ int nb_vps = 0;
649 int vps_list_idx[HEVC_MAX_VPS_COUNT];
650
651
0/2
✗ Branch 6 → 3 not taken.
✗ Branch 6 → 7 not taken.
✗ for (int i = 0; i < HEVC_MAX_VPS_COUNT; i++)
652
0/2
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 5 not taken.
✗ if (h->ps.vps_list[i])
653 ✗ vps_list_idx[nb_vps++] = i;
654
655 ✗ err = alloc_hevc_header_structs(dec, nb_vps, vps_list_idx, h->ps.vps_list);
656
0/2
✗ Branch 8 → 9 not taken.
✗ Branch 8 → 10 not taken.
✗ if (err < 0)
657 ✗ return err;
658
659 ✗ hdr = dec->hevc_headers;
660
661 ✗ h265_params_info.pStdSPSs = hdr->sps;
662 ✗ h265_params_info.pStdPPSs = hdr->pps;
663 ✗ h265_params_info.pStdVPSs = hdr->vps;
664
665 /* SPS list */
666
0/2
✗ Branch 14 → 11 not taken.
✗ Branch 14 → 15 not taken.
✗ for (int i = 0; i < HEVC_MAX_SPS_COUNT; i++) {
667
0/2
✗ Branch 11 → 12 not taken.
✗ Branch 11 → 13 not taken.
✗ if (h->ps.sps_list[i]) {
668 ✗ const HEVCSPS *sps_l = h->ps.sps_list[i];
669 ✗ int idx = h265_params_info.stdSPSCount++;
670 ✗ set_sps(sps_l, i, &hdr->hsps[idx].scaling, &hdr->hsps[idx].vui_header,
671 ✗ &hdr->hsps[idx].vui, &hdr->sps[idx], hdr->hsps[idx].nal_hdr,
672 ✗ hdr->hsps[idx].vcl_hdr, &hdr->hsps[idx].ptl, &hdr->hsps[idx].dpbm,
673 ✗ &hdr->hsps[idx].pal, hdr->hsps[idx].str, &hdr->hsps[idx].ltr);
674 }
675 }
676
677 /* PPS list */
678
0/2
✗ Branch 19 → 16 not taken.
✗ Branch 19 → 20 not taken.
✗ for (int i = 0; i < HEVC_MAX_PPS_COUNT; i++) {
679
0/2
✗ Branch 16 → 17 not taken.
✗ Branch 16 → 18 not taken.
✗ if (h->ps.pps_list[i]) {
680 ✗ const HEVCPPS *pps_l = h->ps.pps_list[i];
681 ✗ const HEVCSPS *sps_l = h->ps.sps_list[pps_l->sps_id];
682 ✗ int idx = h265_params_info.stdPPSCount++;
683 ✗ set_pps(pps_l, sps_l, &hdr->hpps[idx].scaling,
684 &hdr->pps[idx], &hdr->hpps[idx].pal);
685 }
686 }
687
688 /* VPS list */
689
0/2
✗ Branch 23 → 21 not taken.
✗ Branch 23 → 24 not taken.
✗ for (int i = 0; i < nb_vps; i++) {
690 ✗ const HEVCVPS *vps_l = h->ps.vps_list[vps_list_idx[i]];
691 ✗ set_vps(vps_l, &hdr->vps[i], &hdr->hvps[i].ptl, &hdr->hvps[i].dpbm,
692 ✗ hdr->hvps[i].hdr, hdr->hvps[i].sls);
693 ✗ h265_params_info.stdVPSCount++;
694 }
695
696 ✗ h265_params.maxStdSPSCount = h265_params_info.stdSPSCount;
697 ✗ h265_params.maxStdPPSCount = h265_params_info.stdPPSCount;
698 ✗ h265_params.maxStdVPSCount = h265_params_info.stdVPSCount;
699
700 ✗ err = ff_vk_decode_create_params(buf, avctx, ctx, &session_params_create);
701
0/2
✗ Branch 25 → 26 not taken.
✗ Branch 25 → 27 not taken.
✗ if (err < 0)
702 ✗ return err;
703
704 ✗ av_log(avctx, AV_LOG_DEBUG, "Created frame parameters: %i SPS %i PPS %i VPS\n",
705 h265_params_info.stdSPSCount, h265_params_info.stdPPSCount,
706 h265_params_info.stdVPSCount);
707
708 ✗ return 0;
709 }
710
711 ✗ static int vk_hevc_start_frame(AVCodecContext *avctx,
712 av_unused const AVBufferRef *buffer_ref,
713 av_unused const uint8_t *buffer,
714 av_unused uint32_t size)
715 {
716 int err;
717 ✗ HEVCContext *h = avctx->priv_data;
718 ✗ HEVCLayerContext *l = &h->layers[h->cur_layer];
719
720 ✗ HEVCFrame *pic = h->cur_frame;
721 ✗ HEVCVulkanDecodePicture *hp = pic->hwaccel_picture_private;
722 ✗ FFVulkanDecodePicture *vp = &hp->vp;
723 ✗ const HEVCPPS *pps = h->pps;
724 ✗ const HEVCSPS *sps = pps->sps;
725 ✗ int nb_refs = 0;
726
727 ✗ hp->h265pic = (StdVideoDecodeH265PictureInfo) {
728 .flags = (StdVideoDecodeH265PictureInfoFlags) {
729
0/4
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 5 not taken.
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 5 not taken.
✗ .IrapPicFlag = IS_IRAP(h),
730
0/4
✗ Branch 6 → 7 not taken.
✗ Branch 6 → 8 not taken.
✗ Branch 7 → 8 not taken.
✗ Branch 7 → 9 not taken.
✗ .IdrPicFlag = IS_IDR(h),
731
0/2
✗ Branch 10 → 11 not taken.
✗ Branch 10 → 12 not taken.
✗ .IsReference = h->nal_unit_type < 16 ? h->nal_unit_type & 1 : 1,
732 ✗ .short_term_ref_pic_set_sps_flag = h->sh.short_term_ref_pic_set_sps_flag,
733 },
734 ✗ .sps_video_parameter_set_id = sps->vps_id,
735 ✗ .pps_seq_parameter_set_id = pps->sps_id,
736 ✗ .pps_pic_parameter_set_id = pps->pps_id,
737
0/2
✗ Branch 13 → 14 not taken.
✗ Branch 13 → 15 not taken.
✗ .NumDeltaPocsOfRefRpsIdx = h->sh.short_term_rps ? h->sh.short_term_rps->rps_idx_num_delta_pocs : 0,
738 ✗ .PicOrderCntVal = h->poc,
739
0/2
✗ Branch 16 → 17 not taken.
✗ Branch 16 → 18 not taken.
✗ .NumBitsForSTRefPicSetInSlice = !h->sh.short_term_ref_pic_set_sps_flag ?
740 ✗ h->sh.short_term_ref_pic_set_size : 0,
741 };
742
743 /* Fill in references */
744
0/2
✗ Branch 35 → 20 not taken.
✗ Branch 35 → 36 not taken.
✗ for (int i = 0; i < FF_ARRAY_ELEMS(l->DPB); i++) {
745 ✗ const HEVCFrame *ref = &l->DPB[i];
746 ✗ int idx = nb_refs;
747
748
0/2
✗ Branch 20 → 21 not taken.
✗ Branch 20 → 22 not taken.
✗ if (!(ref->flags & (HEVC_FRAME_FLAG_SHORT_REF | HEVC_FRAME_FLAG_LONG_REF)))
749 ✗ continue;
750
751
0/2
✗ Branch 22 → 23 not taken.
✗ Branch 22 → 27 not taken.
✗ if (ref == pic) {
752 ✗ err = vk_hevc_fill_pict(avctx, NULL, &vp->ref_slot, &vp->ref,
753 &hp->vkh265_ref, &hp->h265_ref, pic, 1, i);
754
0/2
✗ Branch 24 → 25 not taken.
✗ Branch 24 → 26 not taken.
✗ if (err < 0)
755 ✗ return err;
756
757 ✗ continue;
758 }
759
760
0/2
✗ Branch 27 → 28 not taken.
✗ Branch 27 → 30 not taken.
✗ if (nb_refs >= HEVC_MAX_REFS) {
761 ✗ av_log(avctx, AV_LOG_ERROR,
762 "Too many reference frames in DPB: %d >= %d\n",
763 nb_refs, HEVC_MAX_REFS);
764 ✗ return AVERROR_INVALIDDATA;
765 }
766
767 ✗ err = vk_hevc_fill_pict(avctx, &hp->ref_src[idx], &vp->ref_slots[idx],
768 &vp->refs[idx], &hp->vkh265_refs[idx],
769 &hp->h265_refs[idx], (HEVCFrame *)ref, 0, i);
770
0/2
✗ Branch 31 → 32 not taken.
✗ Branch 31 → 33 not taken.
✗ if (err < 0)
771 ✗ return err;
772
773 ✗ nb_refs++;
774 }
775
776
0/2
✗ Branch 36 → 37 not taken.
✗ Branch 36 → 39 not taken.
✗ if (h->rps[ST_CURR_BEF].nb_refs > FF_ARRAY_ELEMS(hp->h265pic.RefPicSetStCurrBefore) ||
777
0/2
✗ Branch 37 → 38 not taken.
✗ Branch 37 → 39 not taken.
✗ h->rps[ST_CURR_AFT].nb_refs > FF_ARRAY_ELEMS(hp->h265pic.RefPicSetStCurrAfter) ||
778
0/2
✗ Branch 38 → 39 not taken.
✗ Branch 38 → 41 not taken.
✗ h->rps[LT_CURR].nb_refs > FF_ARRAY_ELEMS(hp->h265pic.RefPicSetLtCurr)) {
779 ✗ av_log(avctx, AV_LOG_ERROR, "Too many reference frames\n");
780 ✗ return AVERROR_INVALIDDATA;
781 }
782
783 ✗ memset(hp->h265pic.RefPicSetStCurrBefore, 0xff, 8);
784
0/2
✗ Branch 48 → 42 not taken.
✗ Branch 48 → 49 not taken.
✗ for (int i = 0; i < h->rps[ST_CURR_BEF].nb_refs; i++) {
785 ✗ HEVCFrame *frame = h->rps[ST_CURR_BEF].ref[i];
786
0/2
✗ Branch 46 → 43 not taken.
✗ Branch 46 → 47 not taken.
✗ for (int j = 0; j < FF_ARRAY_ELEMS(l->DPB); j++) {
787 ✗ const HEVCFrame *ref = &l->DPB[j];
788
0/2
✗ Branch 43 → 44 not taken.
✗ Branch 43 → 45 not taken.
✗ if (ref == frame) {
789 ✗ hp->h265pic.RefPicSetStCurrBefore[i] = j;
790 ✗ break;
791 }
792 }
793 }
794 ✗ memset(hp->h265pic.RefPicSetStCurrAfter, 0xff, 8);
795
0/2
✗ Branch 56 → 50 not taken.
✗ Branch 56 → 57 not taken.
✗ for (int i = 0; i < h->rps[ST_CURR_AFT].nb_refs; i++) {
796 ✗ HEVCFrame *frame = h->rps[ST_CURR_AFT].ref[i];
797
0/2
✗ Branch 54 → 51 not taken.
✗ Branch 54 → 55 not taken.
✗ for (int j = 0; j < FF_ARRAY_ELEMS(l->DPB); j++) {
798 ✗ const HEVCFrame *ref = &l->DPB[j];
799
0/2
✗ Branch 51 → 52 not taken.
✗ Branch 51 → 53 not taken.
✗ if (ref == frame) {
800 ✗ hp->h265pic.RefPicSetStCurrAfter[i] = j;
801 ✗ break;
802 }
803 }
804 }
805 ✗ memset(hp->h265pic.RefPicSetLtCurr, 0xff, 8);
806
0/2
✗ Branch 64 → 58 not taken.
✗ Branch 64 → 65 not taken.
✗ for (int i = 0; i < h->rps[LT_CURR].nb_refs; i++) {
807 ✗ HEVCFrame *frame = h->rps[LT_CURR].ref[i];
808
0/2
✗ Branch 62 → 59 not taken.
✗ Branch 62 → 63 not taken.
✗ for (int j = 0; j < FF_ARRAY_ELEMS(l->DPB); j++) {
809 ✗ const HEVCFrame *ref = &l->DPB[j];
810
0/2
✗ Branch 59 → 60 not taken.
✗ Branch 59 → 61 not taken.
✗ if (ref == frame) {
811 ✗ hp->h265pic.RefPicSetLtCurr[i] = j;
812 ✗ break;
813 }
814 }
815 }
816
817 ✗ hp->h265_pic_info = (VkVideoDecodeH265PictureInfoKHR) {
818 .sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_PICTURE_INFO_KHR,
819 ✗ .pStdPictureInfo = &hp->h265pic,
820 .sliceSegmentCount = 0,
821 };
822
823 ✗ vp->decode_info = (VkVideoDecodeInfoKHR) {
824 .sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_INFO_KHR,
825 ✗ .pNext = &hp->h265_pic_info,
826 .flags = 0x0,
827 ✗ .pSetupReferenceSlot = &vp->ref_slot,
828 .referenceSlotCount = nb_refs,
829 ✗ .pReferenceSlots = vp->ref_slots,
830 .dstPictureResource = (VkVideoPictureResourceInfoKHR) {
831 .sType = VK_STRUCTURE_TYPE_VIDEO_PICTURE_RESOURCE_INFO_KHR,
832 .codedOffset = (VkOffset2D){ 0, 0 },
833 ✗ .codedExtent = (VkExtent2D){ pic->f->width, pic->f->height },
834 .baseArrayLayer = 0,
835 ✗ .imageViewBinding = vp->view.out,
836 },
837 };
838
839 ✗ return 0;
840 }
841
842 ✗ static int vk_hevc_decode_slice(AVCodecContext *avctx,
843 const uint8_t *data,
844 uint32_t size)
845 {
846 ✗ const HEVCContext *h = avctx->priv_data;
847 ✗ HEVCVulkanDecodePicture *hp = h->cur_frame->hwaccel_picture_private;
848 ✗ FFVulkanDecodePicture *vp = &hp->vp;
849
850 ✗ int err = ff_vk_decode_add_slice(avctx, vp, data, size, 1,
851 &hp->h265_pic_info.sliceSegmentCount,
852 &hp->h265_pic_info.pSliceSegmentOffsets);
853
0/2
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 5 not taken.
✗ if (err < 0)
854 ✗ return err;
855
856 ✗ return 0;
857 }
858
859 ✗ static int vk_hevc_end_frame(AVCodecContext *avctx)
860 {
861 ✗ const HEVCContext *h = avctx->priv_data;
862 ✗ FFVulkanDecodeContext *dec = avctx->internal->hwaccel_priv_data;
863 ✗ FFVulkanDecodeShared *ctx = dec->shared_ctx;
864
865 ✗ HEVCFrame *pic = h->cur_frame;
866 ✗ HEVCVulkanDecodePicture *hp = pic->hwaccel_picture_private;
867 ✗ FFVulkanDecodePicture *vp = &hp->vp;
868 ✗ FFVulkanDecodePicture *rvp[HEVC_MAX_REFS] = { 0 };
869 ✗ AVFrame *rav[HEVC_MAX_REFS] = { 0 };
870 int err;
871
872 ✗ const HEVCPPS *pps = h->pps;
873 ✗ const HEVCSPS *sps = pps->sps;
874
875 #ifdef VK_KHR_video_maintenance2
876 VkVideoDecodeH265InlineSessionParametersInfoKHR h265_params;
877
878
0/2
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 10 not taken.
✗ if (ctx->s.extensions & FF_VK_EXT_VIDEO_MAINTENANCE_2) {
879 /* Far too large for the stack; reuse the persistent header buffer,
880 * which the non-inline path never uses at the same time */
881 HEVCHeaderSet *hdr;
882 ✗ const HEVCVPS *vps_list[HEVC_MAX_VPS_COUNT] = { sps->vps };
883 ✗ int vps_list_idx[HEVC_MAX_VPS_COUNT] = { 0 };
884
885 ✗ err = alloc_hevc_header_structs(dec, 1, vps_list_idx, vps_list);
886
0/2
✗ Branch 4 → 5 not taken.
✗ Branch 4 → 6 not taken.
✗ if (err < 0)
887 ✗ return err;
888 ✗ hdr = dec->hevc_headers;
889
890 ✗ set_pps(pps, sps, &hdr->hpps[0].scaling, &hdr->pps[0], &hdr->hpps[0].pal);
891 ✗ set_sps(sps, pps->sps_id, &hdr->hsps[0].scaling, &hdr->hsps[0].vui_header,
892 ✗ &hdr->hsps[0].vui, &hdr->sps[0], hdr->hsps[0].nal_hdr,
893 ✗ hdr->hsps[0].vcl_hdr, &hdr->hsps[0].ptl, &hdr->hsps[0].dpbm,
894 ✗ &hdr->hsps[0].pal, hdr->hsps[0].str, &hdr->hsps[0].ltr);
895
896 ✗ set_vps(sps->vps, &hdr->vps[0], &hdr->hvps[0].ptl, &hdr->hvps[0].dpbm,
897 ✗ hdr->hvps[0].hdr, hdr->hvps[0].sls);
898
899 ✗ h265_params = (VkVideoDecodeH265InlineSessionParametersInfoKHR) {
900 .sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_INLINE_SESSION_PARAMETERS_INFO_KHR,
901 ✗ .pStdSPS = &hdr->sps[0],
902 ✗ .pStdPPS = &hdr->pps[0],
903 ✗ .pStdVPS = &hdr->vps[0],
904 };
905 ✗ hp->h265_pic_info.pNext = &h265_params;
906 }
907 #endif
908
909
0/2
✗ Branch 10 → 11 not taken.
✗ Branch 10 → 12 not taken.
✗ if (!hp->h265_pic_info.sliceSegmentCount)
910 ✗ return 0;
911
912
0/2
✗ Branch 12 → 13 not taken.
✗ Branch 12 → 25 not taken.
✗ if (!dec->session_params &&
913
0/2
✗ Branch 13 → 14 not taken.
✗ Branch 13 → 25 not taken.
✗ !(ctx->s.extensions & FF_VK_EXT_VIDEO_MAINTENANCE_2)) {
914
0/2
✗ Branch 14 → 15 not taken.
✗ Branch 14 → 18 not taken.
✗ if (!pps) {
915 ✗ unsigned int pps_id = h->sh.pps_id;
916
0/4
✗ Branch 15 → 16 not taken.
✗ Branch 15 → 18 not taken.
✗ Branch 16 → 17 not taken.
✗ Branch 16 → 18 not taken.
✗ if (pps_id < HEVC_MAX_PPS_COUNT && h->ps.pps_list[pps_id] != NULL)
917 ✗ pps = h->ps.pps_list[pps_id];
918 }
919
920
0/2
✗ Branch 18 → 19 not taken.
✗ Branch 18 → 21 not taken.
✗ if (!pps) {
921 ✗ av_log(avctx, AV_LOG_ERROR,
922 "Encountered frame without a valid active PPS reference.\n");
923 ✗ return AVERROR_INVALIDDATA;
924 }
925
926 ✗ err = vk_hevc_create_params(avctx, &dec->session_params);
927
0/2
✗ Branch 22 → 23 not taken.
✗ Branch 22 → 24 not taken.
✗ if (err < 0)
928 ✗ return err;
929
930 ✗ hp->h265pic.sps_video_parameter_set_id = sps->vps_id;
931 ✗ hp->h265pic.pps_seq_parameter_set_id = pps->sps_id;
932 ✗ hp->h265pic.pps_pic_parameter_set_id = pps->pps_id;
933 }
934
935
0/2
✗ Branch 27 → 26 not taken.
✗ Branch 27 → 28 not taken.
✗ for (int i = 0; i < vp->decode_info.referenceSlotCount; i++) {
936 ✗ HEVCVulkanDecodePicture *rfhp = hp->ref_src[i]->hwaccel_picture_private;
937 ✗ rav[i] = hp->ref_src[i]->f;
938 ✗ rvp[i] = &rfhp->vp;
939 }
940
941 ✗ av_log(avctx, AV_LOG_DEBUG, "Decoding frame, %zu bytes, %i slices\n",
942 vp->slices_size, hp->h265_pic_info.sliceSegmentCount);
943
944 ✗ return ff_vk_decode_frame(avctx, pic->f, vp, rav, rvp);
945 }
946
947 ✗ static void vk_hevc_free_frame_priv(AVRefStructOpaque _hwctx, void *data)
948 {
949 ✗ AVHWDeviceContext *hwctx = _hwctx.nc;
950 ✗ HEVCVulkanDecodePicture *hp = data;
951
952 /* Free frame resources */
953 ✗ ff_vk_decode_free_frame(hwctx, &hp->vp);
954 ✗ }
955
956 const FFHWAccel ff_hevc_vulkan_hwaccel = {
957 .p.name = "hevc_vulkan",
958 .p.type = AVMEDIA_TYPE_VIDEO,
959 .p.id = AV_CODEC_ID_HEVC,
960 .p.pix_fmt = AV_PIX_FMT_VULKAN,
961 .start_frame = &vk_hevc_start_frame,
962 .decode_slice = &vk_hevc_decode_slice,
963 .end_frame = &vk_hevc_end_frame,
964 .free_frame_priv = &vk_hevc_free_frame_priv,
965 .frame_priv_data_size = sizeof(HEVCVulkanDecodePicture),
966 .init = &ff_vk_decode_init,
967 .update_thread_context = &ff_vk_update_thread_context,
968 .decode_params = &ff_vk_params_invalidate,
969 .uninit = &ff_vk_decode_uninit,
970 .frame_params = &ff_vk_frame_params,
971 .priv_data_size = sizeof(FFVulkanDecodeContext),
972 .caps_internal = HWACCEL_CAP_ASYNC_SAFE,
973 };
974