[FFmpeg-cvslog] vulkan_av1: add workaround for NVIDIA drivers tested on broken CTS

Lynne git at videolan.org
Mon Apr 15 03:42:15 EEST 2024


ffmpeg | branch: master | Lynne <dev at lynne.ee> | Sun Apr 14 14:11:44 2024 +0200| [db09f1a5d811a3ca8adc89c58e29932efd0c255e] | committer: Lynne

vulkan_av1: add workaround for NVIDIA drivers tested on broken CTS

The first release of the CTS for AV1 decoding had incorrect
offsets for the OrderHints values.
The CTS will be fixed, and eventually, the drivers will be
updated to the proper spec-conforming behaviour, but we still
need to add a workaround as this will take months.

Only NVIDIA use these values at all, so limit the workaround
to only NVIDIA. Also, other vendors don't tend to provide accurate
CTS information.

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=db09f1a5d811a3ca8adc89c58e29932efd0c255e
---

 libavcodec/vulkan_av1.c    | 19 +++++++++++++++----
 libavcodec/vulkan_decode.c |  9 +++++++++
 libavcodec/vulkan_decode.h |  4 ++++
 3 files changed, 28 insertions(+), 4 deletions(-)

diff --git a/libavcodec/vulkan_av1.c b/libavcodec/vulkan_av1.c
index fcc9a4f03b..49cd69d051 100644
--- a/libavcodec/vulkan_av1.c
+++ b/libavcodec/vulkan_av1.c
@@ -97,9 +97,14 @@ static int vk_av1_fill_pict(AVCodecContext *avctx, const AV1Frame **ref_src,
         .RefFrameSignBias = hp->ref_frame_sign_bias_mask,
     };
 
-    if (saved_order_hints)
-        for (int i = 0; i < AV1_TOTAL_REFS_PER_FRAME; i++)
-            vkav1_std_ref->SavedOrderHints[i] = saved_order_hints[i];
+    if (saved_order_hints) {
+        if (dec->quirk_av1_offset)
+            for (int i = 1; i < STD_VIDEO_AV1_TOTAL_REFS_PER_FRAME; i++)
+                vkav1_std_ref->SavedOrderHints[i - 1] = saved_order_hints[i];
+        else
+            for (int i = 0; i < STD_VIDEO_AV1_TOTAL_REFS_PER_FRAME; i++)
+                vkav1_std_ref->SavedOrderHints[i] = saved_order_hints[i];
+    }
 
     *vkav1_ref = (VkVideoDecodeAV1DpbSlotInfoKHR) {
         .sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_AV1_DPB_SLOT_INFO_KHR,
@@ -490,8 +495,14 @@ static int vk_av1_start_frame(AVCodecContext          *avctx,
         }
     }
 
+    if (dec->quirk_av1_offset)
+        for (int i = 1; i < STD_VIDEO_AV1_TOTAL_REFS_PER_FRAME; i++)
+            ap->std_pic_info.OrderHints[i - 1] = pic->order_hints[i];
+    else
+        for (int i = 0; i < STD_VIDEO_AV1_TOTAL_REFS_PER_FRAME; i++)
+            ap->std_pic_info.OrderHints[i] = pic->order_hints[i];
+
     for (int i = 0; i < STD_VIDEO_AV1_TOTAL_REFS_PER_FRAME; i++) {
-        ap->std_pic_info.OrderHints[i] = pic->order_hints[i];
         ap->loop_filter.loop_filter_ref_deltas[i] = frame_header->loop_filter_ref_deltas[i];
         ap->global_motion.GmType[i] = s->cur_frame.gm_type[i];
         for (int j = 0; j < STD_VIDEO_AV1_GLOBAL_MOTION_PARAMS; j++) {
diff --git a/libavcodec/vulkan_decode.c b/libavcodec/vulkan_decode.c
index 9c6c2d4efb..d8c75cd0e6 100644
--- a/libavcodec/vulkan_decode.c
+++ b/libavcodec/vulkan_decode.c
@@ -1115,6 +1115,7 @@ int ff_vk_decode_init(AVCodecContext *avctx)
     FFVulkanFunctions *vk;
     const VkVideoProfileInfoKHR *profile;
     const FFVulkanDecodeDescriptor *vk_desc;
+    const VkPhysicalDeviceDriverProperties *driver_props;
 
     VkVideoDecodeH264SessionParametersCreateInfoKHR h264_params = {
         .sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_SESSION_PARAMETERS_CREATE_INFO_KHR,
@@ -1276,6 +1277,14 @@ int ff_vk_decode_init(AVCodecContext *avctx)
         return AVERROR_EXTERNAL;
     }
 
+    driver_props = &dec->shared_ctx->s.driver_props;
+    if (driver_props->driverID == VK_DRIVER_ID_NVIDIA_PROPRIETARY &&
+        driver_props->conformanceVersion.major == 1 &&
+        driver_props->conformanceVersion.minor == 3 &&
+        driver_props->conformanceVersion.subminor == 8 &&
+        driver_props->conformanceVersion.patch < 3)
+        dec->quirk_av1_offset = 1;
+
     ff_vk_decode_flush(avctx);
 
     av_log(avctx, AV_LOG_VERBOSE, "Vulkan decoder initialization sucessful\n");
diff --git a/libavcodec/vulkan_decode.h b/libavcodec/vulkan_decode.h
index 7ba8b239cb..076af93499 100644
--- a/libavcodec/vulkan_decode.h
+++ b/libavcodec/vulkan_decode.h
@@ -72,6 +72,10 @@ typedef struct FFVulkanDecodeContext {
     int external_fg;   /* Oddity  #2 - hardware can't apply film grain */
     uint32_t frame_id_alloc_mask; /* For AV1 only */
 
+    /* Workaround for NVIDIA drivers tested with CTS version 1.3.8 for AV1.
+     * The tests were incorrect as the OrderHints were offset by 1. */
+    int quirk_av1_offset;
+
     /* Thread-local state below */
     struct HEVCHeaderSet *hevc_headers;
     size_t hevc_headers_size;



More information about the ffmpeg-cvslog mailing list