[FFmpeg-devel] [PATCH 6/6] vulkan_hevc: make all temporary structs temporary

Lynne dev at lynne.ee
Mon Mar 31 05:37:42 EEST 2025


---
 libavcodec/vulkan_hevc.c | 291 ++++++++++++++++++++-------------------
 1 file changed, 150 insertions(+), 141 deletions(-)

diff --git a/libavcodec/vulkan_hevc.c b/libavcodec/vulkan_hevc.c
index e83f8346a0..baf8b0c3fd 100644
--- a/libavcodec/vulkan_hevc.c
+++ b/libavcodec/vulkan_hevc.c
@@ -112,85 +112,6 @@ static int alloc_hevc_header_structs(FFVulkanDecodeContext *s,
     return 0;
 }
 
-typedef struct HEVCVulkanDecodePicture {
-    FFVulkanDecodePicture           vp;
-
-    /* Current picture */
-    StdVideoDecodeH265ReferenceInfo h265_ref;
-    VkVideoDecodeH265DpbSlotInfoKHR vkh265_ref;
-
-    /* Picture refs */
-    HEVCFrame                      *ref_src    [HEVC_MAX_REFS];
-    StdVideoDecodeH265ReferenceInfo h265_refs  [HEVC_MAX_REFS];
-    VkVideoDecodeH265DpbSlotInfoKHR vkh265_refs[HEVC_MAX_REFS];
-
-    /* Current picture (contd.) */
-    StdVideoDecodeH265PictureInfo   h265pic;
-    VkVideoDecodeH265PictureInfoKHR h265_pic_info;
-
-    /* Current picture */
-    VkVideoPictureResourceInfoKHR   ref;
-    VkVideoReferenceSlotInfoKHR     ref_slot;
-
-    /* Picture refs. H264 has the maximum number of refs (36) of any supported codec. */
-    VkVideoPictureResourceInfoKHR   refs     [36];
-    VkVideoReferenceSlotInfoKHR     ref_slots[36];
-
-    /* Main decoding struct */
-    VkVideoDecodeInfoKHR            decode_info;
-} HEVCVulkanDecodePicture;
-
-static int vk_hevc_fill_pict(AVCodecContext *avctx, HEVCFrame **ref_src,
-                             VkVideoReferenceSlotInfoKHR *ref_slot,       /* Main structure */
-                             VkVideoPictureResourceInfoKHR *ref,          /* Goes in ^ */
-                             VkVideoDecodeH265DpbSlotInfoKHR *vkh265_ref, /* Goes in ^ */
-                             StdVideoDecodeH265ReferenceInfo *h265_ref,   /* Goes in ^ */
-                             HEVCFrame *pic, int is_current, int pic_id)
-{
-    FFVulkanDecodeContext *dec = avctx->internal->hwaccel_priv_data;
-    FFVulkanDecodeShared *ctx = dec->shared_ctx;
-    HEVCVulkanDecodePicture *hp = pic->hwaccel_picture_private;
-    FFVulkanDecodePicture *vkpic = &hp->vp;
-
-    int err = ff_vk_decode_prepare_frame(dec, pic->f, vkpic, is_current,
-                                         dec->dedicated_dpb);
-    if (err < 0)
-        return err;
-
-    *h265_ref = (StdVideoDecodeH265ReferenceInfo) {
-        .flags = (StdVideoDecodeH265ReferenceInfoFlags) {
-            .used_for_long_term_reference = pic->flags & HEVC_FRAME_FLAG_LONG_REF,
-            .unused_for_reference = 0,
-        },
-        .PicOrderCntVal = pic->poc,
-    };
-
-    *vkh265_ref = (VkVideoDecodeH265DpbSlotInfoKHR) {
-        .sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_DPB_SLOT_INFO_KHR,
-        .pStdReferenceInfo = h265_ref,
-    };
-
-    *ref = (VkVideoPictureResourceInfoKHR) {
-        .sType = VK_STRUCTURE_TYPE_VIDEO_PICTURE_RESOURCE_INFO_KHR,
-        .codedOffset = (VkOffset2D){ 0, 0 },
-        .codedExtent = (VkExtent2D){ pic->f->width, pic->f->height },
-        .baseArrayLayer = ctx->common.layered_dpb ? pic_id : 0,
-        .imageViewBinding = vkpic->view.ref[0],
-    };
-
-    *ref_slot = (VkVideoReferenceSlotInfoKHR) {
-        .sType = VK_STRUCTURE_TYPE_VIDEO_REFERENCE_SLOT_INFO_KHR,
-        .pNext = vkh265_ref,
-        .slotIndex = pic_id,
-        .pPictureResource = ref,
-    };
-
-    if (ref_src)
-        *ref_src = pic;
-
-    return 0;
-}
-
 static void copy_scaling_list(const ScalingList *sl, StdVideoH265ScalingLists *vksl)
 {
     for (int i = 0; i < STD_VIDEO_H265_SCALING_LIST_4X4_NUM_LISTS; i++) {
@@ -719,18 +640,114 @@ static int vk_hevc_create_params(AVCodecContext *avctx, AVBufferRef **buf)
     return 0;
 }
 
+static int vk_hevc_fill_pict(AVCodecContext *avctx, HEVCFrame **ref_src,
+                             VkVideoReferenceSlotInfoKHR *ref_slot,       /* Main structure */
+                             VkVideoPictureResourceInfoKHR *ref,          /* Goes in ^ */
+                             VkVideoDecodeH265DpbSlotInfoKHR *vkh265_ref, /* Goes in ^ */
+                             StdVideoDecodeH265ReferenceInfo *h265_ref,   /* Goes in ^ */
+                             HEVCFrame *pic, int is_current, int pic_id)
+{
+    FFVulkanDecodeContext *dec = avctx->internal->hwaccel_priv_data;
+    FFVulkanDecodeShared *ctx = dec->shared_ctx;
+    FFVulkanDecodePicture *vkpic = pic->hwaccel_picture_private;
+
+    int err = ff_vk_decode_prepare_frame(dec, pic->f, vkpic, is_current,
+                                         dec->dedicated_dpb);
+    if (err < 0)
+        return err;
+
+    *h265_ref = (StdVideoDecodeH265ReferenceInfo) {
+        .flags = (StdVideoDecodeH265ReferenceInfoFlags) {
+            .used_for_long_term_reference = pic->flags & HEVC_FRAME_FLAG_LONG_REF,
+            .unused_for_reference = 0,
+        },
+        .PicOrderCntVal = pic->poc,
+    };
+
+    *vkh265_ref = (VkVideoDecodeH265DpbSlotInfoKHR) {
+        .sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_DPB_SLOT_INFO_KHR,
+        .pStdReferenceInfo = h265_ref,
+    };
+
+    *ref = (VkVideoPictureResourceInfoKHR) {
+        .sType = VK_STRUCTURE_TYPE_VIDEO_PICTURE_RESOURCE_INFO_KHR,
+        .codedOffset = (VkOffset2D){ 0, 0 },
+        .codedExtent = (VkExtent2D){ pic->f->width, pic->f->height },
+        .baseArrayLayer = ctx->common.layered_dpb ? pic_id : 0,
+        .imageViewBinding = vkpic->view.ref[0],
+    };
+
+    *ref_slot = (VkVideoReferenceSlotInfoKHR) {
+        .sType = VK_STRUCTURE_TYPE_VIDEO_REFERENCE_SLOT_INFO_KHR,
+        .pNext = vkh265_ref,
+        .slotIndex = pic_id,
+        .pPictureResource = ref,
+    };
+
+    if (ref_src)
+        *ref_src = pic;
+
+    return 0;
+}
+
 static int vk_hevc_start_frame(AVCodecContext          *avctx,
                                av_unused const AVBufferRef *buffer_ref,
                                av_unused const uint8_t *buffer,
                                av_unused uint32_t       size)
+{
+    const HEVCContext *h = avctx->priv_data;
+    HEVCFrame *pic = h->cur_frame;
+    FFVulkanDecodePicture *vp = pic->hwaccel_picture_private;
+
+    return ff_vk_decode_start_frame(avctx, vp, buffer_ref, 0);
+}
+
+typedef struct HEVCVulkanDecodeParams {
+    /* Current picture */
+    StdVideoDecodeH265ReferenceInfo h265_ref;
+    VkVideoDecodeH265DpbSlotInfoKHR vkh265_ref;
+
+    /* Picture refs */
+    HEVCFrame                      *ref_src    [HEVC_MAX_REFS];
+    StdVideoDecodeH265ReferenceInfo h265_refs  [HEVC_MAX_REFS];
+    VkVideoDecodeH265DpbSlotInfoKHR vkh265_refs[HEVC_MAX_REFS];
+
+    /* Current picture (contd.) */
+    StdVideoDecodeH265PictureInfo   h265pic;
+    VkVideoDecodeH265PictureInfoKHR h265_pic_info;
+
+    /* Current picture */
+    VkVideoPictureResourceInfoKHR   ref;
+    VkVideoReferenceSlotInfoKHR     ref_slot;
+
+    /* Picture refs. H264 has the maximum number of refs (36) of any supported codec. */
+    VkVideoPictureResourceInfoKHR   refs     [36];
+    VkVideoReferenceSlotInfoKHR     ref_slots[36];
+
+    /* Maintenance 2 */
+#ifdef VK_KHR_video_maintenance2
+    HEVCHeaderPPS vkpps_p;
+    StdVideoH265PictureParameterSet vkpps;
+    HEVCHeaderSPS vksps_p;
+    StdVideoH265SequenceParameterSet vksps;
+    HEVCHeaderVPSSet vkvps_ps[HEVC_MAX_SUB_LAYERS];
+    HEVCHeaderVPS vkvps_p;
+    StdVideoH265VideoParameterSet vkvps;
+    VkVideoDecodeH265InlineSessionParametersInfoKHR h265_params;
+#endif
+
+    /* Main decoding struct */
+    VkVideoDecodeInfoKHR            decode_info;
+} HEVCVulkanDecodeParams;
+
+static int vk_hevc_fill_params(AVCodecContext *avctx, FFVulkanDecodePicture *vp,
+                               HEVCVulkanDecodeParams *hp)
 {
     int err;
     HEVCContext *h = avctx->priv_data;
     HEVCLayerContext *l = &h->layers[h->cur_layer];
 
     HEVCFrame *pic = h->cur_frame;
-    HEVCVulkanDecodePicture *hp = pic->hwaccel_picture_private;
-    FFVulkanDecodePicture *vp = &hp->vp;
     const HEVCPPS *pps = h->pps;
     const HEVCSPS *sps = pps->sps;
     int nb_refs = 0;
@@ -814,7 +831,8 @@ static int vk_hevc_start_frame(AVCodecContext          *avctx,
     hp->h265_pic_info = (VkVideoDecodeH265PictureInfoKHR) {
         .sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_PICTURE_INFO_KHR,
         .pStdPictureInfo = &hp->h265pic,
-        .sliceSegmentCount = 0,
+        .pSliceSegmentOffsets = vp->slice_offsets,
+        .sliceSegmentCount = vp->nb_slices,
     };
 
     hp->decode_info = (VkVideoDecodeInfoKHR) {
@@ -836,21 +854,6 @@ static int vk_hevc_start_frame(AVCodecContext          *avctx,
     return 0;
 }
 
-static int vk_hevc_decode_slice(AVCodecContext *avctx,
-                                const uint8_t  *data,
-                                uint32_t        size)
-{
-    const HEVCContext *h = avctx->priv_data;
-    HEVCVulkanDecodePicture *hp = h->cur_frame->hwaccel_picture_private;
-    FFVulkanDecodePicture *vp = &hp->vp;
-
-    int err = ff_vk_decode_add_slice(avctx, vp, data, size, 1);
-    if (err < 0)
-        return err;
-
-    return 0;
-}
-
 static int vk_hevc_end_frame(AVCodecContext *avctx)
 {
     const HEVCContext *h = avctx->priv_data;
@@ -858,53 +861,46 @@ static int vk_hevc_end_frame(AVCodecContext *avctx)
     FFVulkanDecodeShared *ctx = dec->shared_ctx;
 
     HEVCFrame *pic = h->cur_frame;
-    HEVCVulkanDecodePicture *hp = pic->hwaccel_picture_private;
-    FFVulkanDecodePicture *vp = &hp->vp;
+    FFVulkanDecodePicture *vp = pic->hwaccel_picture_private;
     FFVulkanDecodePicture *rvp[HEVC_MAX_REFS] = { 0 };
     AVFrame *rav[HEVC_MAX_REFS] = { 0 };
     int err;
 
+    HEVCVulkanDecodeParams hp = { 0 };
+
     const HEVCPPS *pps = h->pps;
     const HEVCSPS *sps = pps->sps;
 
-#ifdef VK_KHR_video_maintenance2
-    HEVCHeaderPPS vkpps_p;
-    StdVideoH265PictureParameterSet vkpps;
-    HEVCHeaderSPS vksps_p;
-    StdVideoH265SequenceParameterSet vksps;
-    HEVCHeaderVPSSet vkvps_ps[HEVC_MAX_SUB_LAYERS];
-    HEVCHeaderVPS vkvps_p;
-    StdVideoH265VideoParameterSet vkvps;
-    VkVideoDecodeH265InlineSessionParametersInfoKHR h265_params;
+    if (!vp->nb_slices)
+        return 0;
 
+    err = vk_hevc_fill_params(avctx, vp, &hp);
+    if (err < 0)
+        return err;
+
+#ifdef VK_KHR_video_maintenance2
     if (ctx->s.extensions & FF_VK_EXT_VIDEO_MAINTENANCE_2) {
-        set_pps(pps, sps, &vkpps_p.scaling, &vkpps, &vkpps_p.pal);
-        set_sps(sps, pps->sps_id, &vksps_p.scaling, &vksps_p.vui_header,
-                &vksps_p.vui, &vksps, vksps_p.nal_hdr,
-                vksps_p.vcl_hdr, &vksps_p.ptl, &vksps_p.dpbm,
-                &vksps_p.pal, vksps_p.str, &vksps_p.ltr);
+        set_pps(pps, sps, &hp.vkpps_p.scaling, &hp.vkpps, &hp.vkpps_p.pal);
+        set_sps(sps, pps->sps_id, &hp.vksps_p.scaling, &hp.vksps_p.vui_header,
+                &hp.vksps_p.vui, &hp.vksps, hp.vksps_p.nal_hdr,
+                hp.vksps_p.vcl_hdr, &hp.vksps_p.ptl, &hp.vksps_p.dpbm,
+                &hp.vksps_p.pal, hp.vksps_p.str, &hp.vksps_p.ltr);
 
-        vkvps_p.sls = vkvps_ps;
-        set_vps(sps->vps, &vkvps, &vkvps_p.ptl, &vkvps_p.dpbm,
-                vkvps_p.hdr, vkvps_p.sls);
+        hp.vkvps_p.sls = hp.vkvps_ps;
+        set_vps(sps->vps, &hp.vkvps, &hp.vkvps_p.ptl, &hp.vkvps_p.dpbm,
+                hp.vkvps_p.hdr, hp.vkvps_p.sls);
 
-        h265_params = (VkVideoDecodeH265InlineSessionParametersInfoKHR) {
+        hp.h265_params = (VkVideoDecodeH265InlineSessionParametersInfoKHR) {
             .sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_INLINE_SESSION_PARAMETERS_INFO_KHR,
-            .pStdSPS = &vksps,
-            .pStdPPS = &vkpps,
-            .pStdVPS = &vkvps,
+            .pStdSPS = &hp.vksps,
+            .pStdPPS = &hp.vkpps,
+            .pStdVPS = &hp.vkvps,
         };
-        hp->h265_pic_info.pNext = &h265_params;
-    }
+        hp.h265_pic_info.pNext = &hp.h265_params;
+    } else
 #endif
 
-    hp->h265_pic_info.pSliceSegmentOffsets = vp->slice_offsets;
-    hp->h265_pic_info.sliceSegmentCount = vp->nb_slices;
-    if (!hp->h265_pic_info.sliceSegmentCount)
-        return 0;
-
-    if (!dec->session_params &&
-        !(ctx->s.extensions & FF_VK_EXT_VIDEO_MAINTENANCE_2)) {
+    if (!dec->session_params) {
         if (!pps) {
             unsigned int pps_id = h->sh.pps_id;
             if (pps_id < HEVC_MAX_PPS_COUNT && h->ps.pps_list[pps_id] != NULL)
@@ -921,31 +917,44 @@ static int vk_hevc_end_frame(AVCodecContext *avctx)
         if (err < 0)
             return err;
 
-        hp->h265pic.sps_video_parameter_set_id = sps->vps_id;
-        hp->h265pic.pps_seq_parameter_set_id = pps->sps_id;
-        hp->h265pic.pps_pic_parameter_set_id = pps->pps_id;
+        hp.h265pic.sps_video_parameter_set_id = sps->vps_id;
+        hp.h265pic.pps_seq_parameter_set_id = pps->sps_id;
+        hp.h265pic.pps_pic_parameter_set_id = pps->pps_id;
     }
 
-    for (int i = 0; i < hp->decode_info.referenceSlotCount; i++) {
-        HEVCVulkanDecodePicture *rfhp = hp->ref_src[i]->hwaccel_picture_private;
-        rav[i] = hp->ref_src[i]->f;
-        rvp[i] = &rfhp->vp;
+    for (int i = 0; i < hp.decode_info.referenceSlotCount; i++) {
+        rav[i] = hp.ref_src[i]->f;
+        rvp[i] = hp.ref_src[i]->hwaccel_picture_private;
     }
 
     av_log(avctx, AV_LOG_VERBOSE, "Decoding frame, %"SIZE_SPECIFIER" bytes, %i slices\n",
-           vp->slices_size, hp->h265_pic_info.sliceSegmentCount);
+           vp->slices_size, hp.h265_pic_info.sliceSegmentCount);
 
-    return ff_vk_decode_frame(avctx, &hp->decode_info,
+    return ff_vk_decode_frame(avctx, &hp.decode_info,
                               pic->f, vp, rav, rvp);
 }
 
+static int vk_hevc_decode_slice(AVCodecContext *avctx,
+                                const uint8_t  *data,
+                                uint32_t        size)
+{
+    const HEVCContext *h = avctx->priv_data;
+    FFVulkanDecodePicture *vp = h->cur_frame->hwaccel_picture_private;
+
+    int err = ff_vk_decode_add_slice(avctx, vp, data, size, 1);
+    if (err < 0)
+        return err;
+
+    return 0;
+}
+
 static void vk_hevc_free_frame_priv(AVRefStructOpaque _hwctx, void *data)
 {
     AVHWDeviceContext *hwctx = _hwctx.nc;
-    HEVCVulkanDecodePicture *hp = data;
+    FFVulkanDecodePicture *vp = data;
 
     /* Free frame resources */
-    ff_vk_decode_free_frame(hwctx, &hp->vp);
+    ff_vk_decode_free_frame(hwctx, vp);
 }
 
 const FFHWAccel ff_hevc_vulkan_hwaccel = {
@@ -957,7 +966,7 @@ const FFHWAccel ff_hevc_vulkan_hwaccel = {
     .decode_slice          = &vk_hevc_decode_slice,
     .end_frame             = &vk_hevc_end_frame,
     .free_frame_priv       = &vk_hevc_free_frame_priv,
-    .frame_priv_data_size  = sizeof(HEVCVulkanDecodePicture),
+    .frame_priv_data_size  = sizeof(FFVulkanDecodePicture),
     .init                  = &ff_vk_decode_init,
     .update_thread_context = &ff_vk_update_thread_context,
     .decode_params         = &ff_vk_params_invalidate,
-- 
2.49.0


More information about the ffmpeg-devel mailing list