mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-11-26 19:01:44 +02:00
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.
This commit is contained in:
parent
3cca8dfbd8
commit
db09f1a5d8
@ -97,9 +97,14 @@ static int vk_av1_fill_pict(AVCodecContext *avctx, const AV1Frame **ref_src,
|
|||||||
.RefFrameSignBias = hp->ref_frame_sign_bias_mask,
|
.RefFrameSignBias = hp->ref_frame_sign_bias_mask,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (saved_order_hints)
|
if (saved_order_hints) {
|
||||||
for (int i = 0; i < AV1_TOTAL_REFS_PER_FRAME; i++)
|
if (dec->quirk_av1_offset)
|
||||||
vkav1_std_ref->SavedOrderHints[i] = saved_order_hints[i];
|
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) {
|
*vkav1_ref = (VkVideoDecodeAV1DpbSlotInfoKHR) {
|
||||||
.sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_AV1_DPB_SLOT_INFO_KHR,
|
.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++) {
|
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->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];
|
ap->global_motion.GmType[i] = s->cur_frame.gm_type[i];
|
||||||
for (int j = 0; j < STD_VIDEO_AV1_GLOBAL_MOTION_PARAMS; j++) {
|
for (int j = 0; j < STD_VIDEO_AV1_GLOBAL_MOTION_PARAMS; j++) {
|
||||||
|
@ -1115,6 +1115,7 @@ int ff_vk_decode_init(AVCodecContext *avctx)
|
|||||||
FFVulkanFunctions *vk;
|
FFVulkanFunctions *vk;
|
||||||
const VkVideoProfileInfoKHR *profile;
|
const VkVideoProfileInfoKHR *profile;
|
||||||
const FFVulkanDecodeDescriptor *vk_desc;
|
const FFVulkanDecodeDescriptor *vk_desc;
|
||||||
|
const VkPhysicalDeviceDriverProperties *driver_props;
|
||||||
|
|
||||||
VkVideoDecodeH264SessionParametersCreateInfoKHR h264_params = {
|
VkVideoDecodeH264SessionParametersCreateInfoKHR h264_params = {
|
||||||
.sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_SESSION_PARAMETERS_CREATE_INFO_KHR,
|
.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;
|
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);
|
ff_vk_decode_flush(avctx);
|
||||||
|
|
||||||
av_log(avctx, AV_LOG_VERBOSE, "Vulkan decoder initialization sucessful\n");
|
av_log(avctx, AV_LOG_VERBOSE, "Vulkan decoder initialization sucessful\n");
|
||||||
|
@ -72,6 +72,10 @@ typedef struct FFVulkanDecodeContext {
|
|||||||
int external_fg; /* Oddity #2 - hardware can't apply film grain */
|
int external_fg; /* Oddity #2 - hardware can't apply film grain */
|
||||||
uint32_t frame_id_alloc_mask; /* For AV1 only */
|
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 */
|
/* Thread-local state below */
|
||||||
struct HEVCHeaderSet *hevc_headers;
|
struct HEVCHeaderSet *hevc_headers;
|
||||||
size_t hevc_headers_size;
|
size_t hevc_headers_size;
|
||||||
|
Loading…
Reference in New Issue
Block a user