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 | ✗ | 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 | ✗ | 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 | ✗ | 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 | ✗ | 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 | ✗ | 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 | ✗ | .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 | ✗ | 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 | ✗ | for (int i = 0; i < STD_VIDEO_H265_SCALING_LIST_4X4_NUM_LISTS; i++) { | |
| 186 | ✗ | 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 | ✗ | for (int i = 0; i < STD_VIDEO_H265_SCALING_LIST_8X8_NUM_LISTS; i++) { | |
| 193 | ✗ | 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 | ✗ | for (int i = 0; i < STD_VIDEO_H265_SCALING_LIST_16X16_NUM_LISTS; i++) { | |
| 200 | ✗ | 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 | ✗ | for (int i = 0; i < STD_VIDEO_H265_SCALING_LIST_32X32_NUM_LISTS; i++) { | |
| 207 | ✗ | 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 | ✗ | 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 | ✗ | 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 | ✗ | for (int i = 0; i < (sps->chroma_format_idc ? 3 : 1); i++) | |
| 333 | ✗ | 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 | ✗ | 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 | ✗ | for (int j = 0; j < str[i].num_negative_pics; j++) | |
| 364 | ✗ | str[i].delta_poc_s0_minus1[j] = st_rps->delta_poc[j] - (j ? st_rps->delta_poc[j - 1] : 0) - 1; | |
| 365 | |||
| 366 | ✗ | for (int j = 0; j < str[i].num_positive_pics; j++) | |
| 367 | ✗ | 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 | ✗ | 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 | ✗ | for (int i = 0; i < (pps->monochrome_palette_flag ? 1 : 3); i++) { | |
| 525 | ✗ | 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 | ✗ | for (int i = 0; i < pps->num_tile_columns - 1; i++) | |
| 530 | ✗ | vkpps->column_width_minus1[i] = pps->column_width[i] - 1; | |
| 531 | |||
| 532 | ✗ | for (int i = 0; i < pps->num_tile_rows - 1; i++) | |
| 533 | ✗ | vkpps->row_height_minus1[i] = pps->row_height[i] - 1; | |
| 534 | |||
| 535 | ✗ | 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 | ✗ | 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 | ✗ | 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 | ✗ | for (int i = 0; i < HEVC_MAX_VPS_COUNT; i++) | |
| 652 | ✗ | 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 | ✗ | 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 | ✗ | for (int i = 0; i < HEVC_MAX_SPS_COUNT; i++) { | |
| 667 | ✗ | 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 | ✗ | for (int i = 0; i < HEVC_MAX_PPS_COUNT; i++) { | |
| 679 | ✗ | 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 | ✗ | 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 | ✗ | 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 | ✗ | .IrapPicFlag = IS_IRAP(h), | |
| 730 | ✗ | .IdrPicFlag = IS_IDR(h), | |
| 731 | ✗ | .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 | ✗ | .NumDeltaPocsOfRefRpsIdx = h->sh.short_term_rps ? h->sh.short_term_rps->rps_idx_num_delta_pocs : 0, | |
| 738 | ✗ | .PicOrderCntVal = h->poc, | |
| 739 | ✗ | .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 | ✗ | 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 | ✗ | if (!(ref->flags & (HEVC_FRAME_FLAG_SHORT_REF | HEVC_FRAME_FLAG_LONG_REF))) | |
| 749 | ✗ | continue; | |
| 750 | |||
| 751 | ✗ | 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 | ✗ | if (err < 0) | |
| 755 | ✗ | return err; | |
| 756 | |||
| 757 | ✗ | continue; | |
| 758 | } | ||
| 759 | |||
| 760 | ✗ | 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 | ✗ | if (err < 0) | |
| 771 | ✗ | return err; | |
| 772 | |||
| 773 | ✗ | nb_refs++; | |
| 774 | } | ||
| 775 | |||
| 776 | ✗ | if (h->rps[ST_CURR_BEF].nb_refs > FF_ARRAY_ELEMS(hp->h265pic.RefPicSetStCurrBefore) || | |
| 777 | ✗ | h->rps[ST_CURR_AFT].nb_refs > FF_ARRAY_ELEMS(hp->h265pic.RefPicSetStCurrAfter) || | |
| 778 | ✗ | 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 | ✗ | for (int i = 0; i < h->rps[ST_CURR_BEF].nb_refs; i++) { | |
| 785 | ✗ | HEVCFrame *frame = h->rps[ST_CURR_BEF].ref[i]; | |
| 786 | ✗ | for (int j = 0; j < FF_ARRAY_ELEMS(l->DPB); j++) { | |
| 787 | ✗ | const HEVCFrame *ref = &l->DPB[j]; | |
| 788 | ✗ | if (ref == frame) { | |
| 789 | ✗ | hp->h265pic.RefPicSetStCurrBefore[i] = j; | |
| 790 | ✗ | break; | |
| 791 | } | ||
| 792 | } | ||
| 793 | } | ||
| 794 | ✗ | memset(hp->h265pic.RefPicSetStCurrAfter, 0xff, 8); | |
| 795 | ✗ | for (int i = 0; i < h->rps[ST_CURR_AFT].nb_refs; i++) { | |
| 796 | ✗ | HEVCFrame *frame = h->rps[ST_CURR_AFT].ref[i]; | |
| 797 | ✗ | for (int j = 0; j < FF_ARRAY_ELEMS(l->DPB); j++) { | |
| 798 | ✗ | const HEVCFrame *ref = &l->DPB[j]; | |
| 799 | ✗ | if (ref == frame) { | |
| 800 | ✗ | hp->h265pic.RefPicSetStCurrAfter[i] = j; | |
| 801 | ✗ | break; | |
| 802 | } | ||
| 803 | } | ||
| 804 | } | ||
| 805 | ✗ | memset(hp->h265pic.RefPicSetLtCurr, 0xff, 8); | |
| 806 | ✗ | for (int i = 0; i < h->rps[LT_CURR].nb_refs; i++) { | |
| 807 | ✗ | HEVCFrame *frame = h->rps[LT_CURR].ref[i]; | |
| 808 | ✗ | for (int j = 0; j < FF_ARRAY_ELEMS(l->DPB); j++) { | |
| 809 | ✗ | const HEVCFrame *ref = &l->DPB[j]; | |
| 810 | ✗ | 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 | ✗ | 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 | ✗ | 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 | ✗ | 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 | ✗ | if (!hp->h265_pic_info.sliceSegmentCount) | |
| 910 | ✗ | return 0; | |
| 911 | |||
| 912 | ✗ | if (!dec->session_params && | |
| 913 | ✗ | !(ctx->s.extensions & FF_VK_EXT_VIDEO_MAINTENANCE_2)) { | |
| 914 | ✗ | if (!pps) { | |
| 915 | ✗ | unsigned int pps_id = h->sh.pps_id; | |
| 916 | ✗ | 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 | ✗ | 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 | ✗ | 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 | ✗ | 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 |