diff mbox series

[FFmpeg-devel] vulkan_decode: simplify and make session parameter generation more robust

Message ID NYTrO-A--7-9@lynne.ee
State New
Headers show
Series [FFmpeg-devel] vulkan_decode: simplify and make session parameter generation more robust | expand

Checks

Context Check Description
yinshiyou/configure_loongarch64 warning Failed to apply patch
andriy/configure_x86 warning Failed to apply patch

Commit Message

Lynne June 21, 2023, 4:50 p.m. UTC
This commit scraps a bool to signal to recreate the session parameters,
but instead destroys them, forcing them to be recreated.

As this can happen between start_frame and end_frame, do this
at both places.
diff mbox series

Patch

From eb6e92f599f8fa7689f16c3ac99f33eedf79b5a8 Mon Sep 17 00:00:00 2001
From: Lynne <dev@lynne.ee>
Date: Wed, 21 Jun 2023 18:24:55 +0200
Subject: [PATCH] vulkan_decode: simplify and make session parameter generation
 more robust

This commit scraps a bool to signal to recreate the session parameters,
but instead destroys them, forcing them to be recreated.

As this can happen between start_frame and end_frame, do this
at both places.
---
 libavcodec/vulkan_av1.c    | 13 +++++++++----
 libavcodec/vulkan_decode.c |  4 ++--
 libavcodec/vulkan_decode.h |  5 ++---
 libavcodec/vulkan_h264.c   | 16 ++++++++++------
 libavcodec/vulkan_hevc.c   | 20 ++++++++++++++++----
 5 files changed, 39 insertions(+), 19 deletions(-)

diff --git a/libavcodec/vulkan_av1.c b/libavcodec/vulkan_av1.c
index 91e44ba803..e6d77df7e4 100644
--- a/libavcodec/vulkan_av1.c
+++ b/libavcodec/vulkan_av1.c
@@ -229,12 +229,10 @@  static int vk_av1_start_frame(AVCodecContext          *avctx,
     const int apply_grain = !(avctx->export_side_data & AV_CODEC_EXPORT_DATA_FILM_GRAIN) &&
                             film_grain->apply_grain;
 
-    if (!dec->session_params || dec->params_changed) {
-        av_buffer_unref(&dec->session_params);
+    if (!dec->session_params) {
         err = vk_av1_create_params(avctx, &dec->session_params);
         if (err < 0)
             return err;
-        dec->params_changed = 0;
     }
 
     if (!ap->frame_id_set) {
@@ -528,12 +526,19 @@  static int vk_av1_decode_slice(AVCodecContext *avctx,
 static int vk_av1_end_frame(AVCodecContext *avctx)
 {
     const AV1DecContext *s = avctx->priv_data;
+    FFVulkanDecodeContext *dec = avctx->internal->hwaccel_priv_data;
     const AV1Frame *pic = &s->cur_frame;
     AV1VulkanDecodePicture *ap = pic->hwaccel_picture_private;
     FFVulkanDecodePicture *vp = &ap->vp;
     FFVulkanDecodePicture *rvp[AV1_NUM_REF_FRAMES] = { 0 };
     AVFrame *rav[AV1_NUM_REF_FRAMES] = { 0 };
 
+    if (!dec->session_params) {
+        int err = vk_av1_create_params(avctx, &dec->session_params);
+        if (err < 0)
+            return err;
+    }
+
     for (int i = 0; i < vp->decode_info.referenceSlotCount; i++) {
         const AV1Frame *rp = ap->ref_src[i];
         AV1VulkanDecodePicture *rhp = rp->hwaccel_picture_private;
@@ -576,7 +581,7 @@  const AVHWAccel ff_av1_vulkan_hwaccel = {
     .frame_priv_data_size  = sizeof(AV1VulkanDecodePicture),
     .init                  = &ff_vk_decode_init,
     .update_thread_context = &ff_vk_update_thread_context,
-    .decode_params         = &ff_vk_params_changed,
+    .decode_params         = &ff_vk_params_invalidate,
     .flush                 = &ff_vk_decode_flush,
     .uninit                = &ff_vk_decode_uninit,
     .frame_params          = &ff_vk_frame_params,
diff --git a/libavcodec/vulkan_decode.c b/libavcodec/vulkan_decode.c
index 685e300e8a..973c7ca548 100644
--- a/libavcodec/vulkan_decode.c
+++ b/libavcodec/vulkan_decode.c
@@ -66,10 +66,10 @@  int ff_vk_update_thread_context(AVCodecContext *dst, const AVCodecContext *src)
     return 0;
 }
 
-int ff_vk_params_changed(AVCodecContext *avctx, int t, const uint8_t *b, uint32_t s)
+int ff_vk_params_invalidate(AVCodecContext *avctx, int t, const uint8_t *b, uint32_t s)
 {
     FFVulkanDecodeContext *dec = avctx->internal->hwaccel_priv_data;
-    dec->params_changed = 1;
+    av_buffer_unref(&dec->session_params);
     return 0;
 }
 
diff --git a/libavcodec/vulkan_decode.h b/libavcodec/vulkan_decode.h
index 776538a335..4e45cbde71 100644
--- a/libavcodec/vulkan_decode.h
+++ b/libavcodec/vulkan_decode.h
@@ -65,7 +65,6 @@  typedef struct FFVulkanDecodeContext {
     /* Thread-local state below */
     AVBufferPool *tmp_pool; /* Pool for temporary data, if needed (HEVC) */
     size_t tmp_pool_ele_size;
-    int params_changed;
 
     uint32_t                       *slice_off;
     unsigned int                    slice_off_max;
@@ -119,9 +118,9 @@  int ff_vk_update_thread_context(AVCodecContext *dst, const AVCodecContext *src);
 int ff_vk_frame_params(AVCodecContext *avctx, AVBufferRef *hw_frames_ctx);
 
 /**
- * Sets FFVulkanDecodeContext.params_changed to 1.
+ * Removes current session parameters to recreate them
  */
-int ff_vk_params_changed(AVCodecContext *avctx, int t, const uint8_t *b, uint32_t s);
+int ff_vk_params_invalidate(AVCodecContext *avctx, int t, const uint8_t *b, uint32_t s);
 
 /**
  * Prepare a frame, creates the image view, and sets up the dpb fields.
diff --git a/libavcodec/vulkan_h264.c b/libavcodec/vulkan_h264.c
index d0b66734d1..62e350266a 100644
--- a/libavcodec/vulkan_h264.c
+++ b/libavcodec/vulkan_h264.c
@@ -379,12 +379,10 @@  static int vk_h264_start_frame(AVCodecContext          *avctx,
     H264VulkanDecodePicture *hp = pic->hwaccel_picture_private;
     FFVulkanDecodePicture *vp = &hp->vp;
 
-    if (!dec->session_params || dec->params_changed) {
-        av_buffer_unref(&dec->session_params);
+    if (!dec->session_params) {
         err = vk_h264_create_params(avctx, &dec->session_params);
         if (err < 0)
             return err;
-        dec->params_changed = 0;
     }
 
     /* Fill in main slot */
@@ -519,8 +517,14 @@  static int vk_h264_end_frame(AVCodecContext *avctx)
     FFVulkanDecodePicture *rvp[H264_MAX_PICTURE_COUNT] = { 0 };
     AVFrame *rav[H264_MAX_PICTURE_COUNT] = { 0 };
 
-    if (!dec->session_params)
-        return AVERROR(EINVAL);
+    if (!dec->session_params) {
+        int err = vk_h264_create_params(avctx, &dec->session_params);
+        if (err < 0)
+            return err;
+
+        hp->h264pic.seq_parameter_set_id = pic->pps->sps_id;
+        hp->h264pic.pic_parameter_set_id = pic->pps->pps_id;
+    }
 
     for (int i = 0; i < vp->decode_info.referenceSlotCount; i++) {
         H264Picture *rp = hp->ref_src[i];
@@ -560,7 +564,7 @@  const AVHWAccel ff_h264_vulkan_hwaccel = {
     .frame_priv_data_size  = sizeof(H264VulkanDecodePicture),
     .init                  = &ff_vk_decode_init,
     .update_thread_context = &ff_vk_update_thread_context,
-    .decode_params         = &ff_vk_params_changed,
+    .decode_params         = &ff_vk_params_invalidate,
     .flush                 = &ff_vk_decode_flush,
     .uninit                = &ff_vk_decode_uninit,
     .frame_params          = &ff_vk_frame_params,
diff --git a/libavcodec/vulkan_hevc.c b/libavcodec/vulkan_hevc.c
index a1df0766fa..5894086821 100644
--- a/libavcodec/vulkan_hevc.c
+++ b/libavcodec/vulkan_hevc.c
@@ -767,12 +767,10 @@  static int vk_hevc_start_frame(AVCodecContext          *avctx,
     const HEVCPPS *pps = h->ps.pps;
     int nb_refs = 0;
 
-    if (!dec->session_params || dec->params_changed) {
-        av_buffer_unref(&dec->session_params);
+    if (!dec->session_params) {
         err = vk_hevc_create_params(avctx, &dec->session_params);
         if (err < 0)
             return err;
-        dec->params_changed = 0;
     }
 
     hp->h265pic = (StdVideoDecodeH265PictureInfo) {
@@ -896,12 +894,26 @@  static int vk_hevc_decode_slice(AVCodecContext *avctx,
 static int vk_hevc_end_frame(AVCodecContext *avctx)
 {
     const HEVCContext *h = avctx->priv_data;
+    FFVulkanDecodeContext *dec = avctx->internal->hwaccel_priv_data;
     HEVCFrame *pic = h->ref;
     HEVCVulkanDecodePicture *hp = pic->hwaccel_picture_private;
     FFVulkanDecodePicture *vp = &hp->vp;
     FFVulkanDecodePicture *rvp[HEVC_MAX_REFS] = { 0 };
     AVFrame *rav[HEVC_MAX_REFS] = { 0 };
 
+    if (!dec->session_params) {
+        const HEVCSPS *sps = h->ps.sps;
+        const HEVCPPS *pps = h->ps.pps;
+
+        int err = vk_hevc_create_params(avctx, &dec->session_params);
+        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;
+    }
+
     for (int i = 0; i < vp->decode_info.referenceSlotCount; i++) {
         HEVCVulkanDecodePicture *rfhp = hp->ref_src[i]->hwaccel_picture_private;
         rav[i] = hp->ref_src[i]->frame;
@@ -938,7 +950,7 @@  const AVHWAccel ff_hevc_vulkan_hwaccel = {
     .frame_priv_data_size  = sizeof(HEVCVulkanDecodePicture),
     .init                  = &ff_vk_decode_init,
     .update_thread_context = &ff_vk_update_thread_context,
-    .decode_params         = &ff_vk_params_changed,
+    .decode_params         = &ff_vk_params_invalidate,
     .flush                 = &ff_vk_decode_flush,
     .uninit                = &ff_vk_decode_uninit,
     .frame_params          = &ff_vk_frame_params,
-- 
2.40.1