@@ -28,22 +28,29 @@ typedef struct VkCodecMap {
VkVideoCodecOperationFlagBitsKHR decode_op;
} VkCodecMap;
+/* The following table and dec_ext below are supposed to be parallel. */
static const VkCodecMap vk_codec_map[] = {
+#if CONFIG_H264_VULKAN_HWACCEL
{
.codec_id = AV_CODEC_ID_H264,
.decode_extension = FF_VK_EXT_VIDEO_DECODE_H264,
.decode_op = VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR,
},
+#endif
+#if CONFIG_HEVC_VULKAN_HWACCEL
{
.codec_id = AV_CODEC_ID_HEVC,
.decode_extension = FF_VK_EXT_VIDEO_DECODE_H265,
.decode_op = VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_KHR,
},
+#endif
+#if CONFIG_AV1_VULKAN_HWACCEL
{
.codec_id = AV_CODEC_ID_AV1,
.decode_extension = FF_VK_EXT_VIDEO_DECODE_AV1,
.decode_op = 0x01000000, /* TODO fix this */
},
+#endif
};
#if CONFIG_H264_VULKAN_HWACCEL
@@ -58,16 +65,19 @@ extern const VkExtensionProperties ff_vk_dec_av1_ext;
static const VkExtensionProperties *dec_ext[] = {
#if CONFIG_H264_VULKAN_HWACCEL
- [AV_CODEC_ID_H264] = &ff_vk_dec_h264_ext,
+ &ff_vk_dec_h264_ext,
#endif
#if CONFIG_HEVC_VULKAN_HWACCEL
- [AV_CODEC_ID_HEVC] = &ff_vk_dec_hevc_ext,
+ &ff_vk_dec_hevc_ext,
#endif
#if CONFIG_AV1_VULKAN_HWACCEL
- [AV_CODEC_ID_AV1] = &ff_vk_dec_av1_ext,
+ &ff_vk_dec_av1_ext,
#endif
};
+_Static_assert(FF_ARRAY_ELEMS(dec_ext) == FF_ARRAY_ELEMS(vk_codec_map),
+ "dec_ext and vk_codec_map out-of-sync");
+
static const VkCodecMap *get_codecmap(enum AVCodecID codec_id)
{
for (size_t i = 0; i < FF_ARRAY_ELEMS(vk_codec_map); i++)
@@ -77,6 +87,11 @@ static const VkCodecMap *get_codecmap(enum AVCodecID codec_id)
return NULL;
}
+static const VkExtensionProperties *get_extension(const VkCodecMap *vk_codec)
+{
+ return dec_ext[vk_codec - vk_codec_map];
+}
+
static const VkVideoProfileInfoKHR *get_video_profile(FFVulkanDecodeShared *ctx, enum AVCodecID codec_id)
{
const VkVideoProfileListInfoKHR *profile_list;
@@ -772,6 +787,7 @@ static int vulkan_decode_get_profile(AVCodecContext *avctx, AVBufferRef *frames_
VkResult ret;
int max_level, base_profile, cur_profile;
const VkCodecMap *vk_codec = get_codecmap(avctx->codec_id);
+ const VkExtensionProperties *extension = get_extension(vk_codec);
AVHWFramesContext *frames = (AVHWFramesContext *)frames_ref->data;
AVHWDeviceContext *device = (AVHWDeviceContext *)frames->device_ref->data;
AVVulkanDeviceContext *hwctx = device->hwctx;
@@ -890,10 +906,10 @@ static int vulkan_decode_get_profile(AVCodecContext *avctx, AVBufferRef *frames_
caps->maxActiveReferencePictures);
av_log(avctx, AV_LOG_VERBOSE, " Codec header name: '%s' (driver), '%s' (compiled)\n",
caps->stdHeaderVersion.extensionName,
- dec_ext[avctx->codec_id]->extensionName);
+ extension->extensionName);
av_log(avctx, AV_LOG_VERBOSE, " Codec header version: %i.%i.%i (driver), %i.%i.%i (compiled)\n",
CODEC_VER(caps->stdHeaderVersion.specVersion),
- CODEC_VER(dec_ext[avctx->codec_id]->specVersion));
+ CODEC_VER(extension->specVersion));
av_log(avctx, AV_LOG_VERBOSE, " Decode modes:%s%s%s\n",
dec_caps->flags ? "" :
" invalid",
@@ -1221,7 +1237,7 @@ int ff_vk_decode_init(AVCodecContext *avctx)
session_create.maxActiveReferencePictures = ctx->caps.maxActiveReferencePictures;
session_create.pictureFormat = s->hwfc->format[0];
session_create.referencePictureFormat = session_create.pictureFormat;
- session_create.pStdHeaderVersion = dec_ext[avctx->codec_id];
+ session_create.pStdHeaderVersion = get_extension(vk_codec);
session_create.pVideoProfile = profile;
/* Create decode exec context for this specific main thread.
Only three of the 226 (== AV_CODEC_ID_AV1) entries have been used. Unsparsing this table is especially important given that this array lives in .data.rel.ro. Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com> --- Instead of parallel tables, one could also merge VkCodecMap and VkExtensionProperties (i.e. putting one of the latter inside the former) if preferred. libavcodec/vulkan_decode.c | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-)