1
0
mirror of https://github.com/FFmpeg/FFmpeg.git synced 2025-08-10 06:10:52 +02:00

lavc: add an av1_vulkan encoder

This commit adds a Vulkan AV1 encoder, using the native acceleration API.
This commit is contained in:
Lynne
2025-04-14 09:19:55 +02:00
parent 2caf23e7c4
commit b2928971e8
9 changed files with 1477 additions and 0 deletions

1
configure vendored
View File

@@ -3400,6 +3400,7 @@ av1_qsv_encoder_deps="libvpl"
av1_qsv_encoder_select="qsvenc"
av1_vaapi_encoder_deps="VAEncPictureParameterBufferAV1"
av1_vaapi_encoder_select="cbs_av1 vaapi_encode"
av1_vulkan_encoder_select="cbs_av1 vulkan_encode"
h263_v4l2m2m_decoder_deps="v4l2_m2m h263_v4l2_m2m"
h263_v4l2m2m_encoder_deps="v4l2_m2m h263_v4l2_m2m"
h264_amf_encoder_deps="amf"

View File

@@ -272,6 +272,8 @@ OBJS-$(CONFIG_AV1_MEDIACODEC_ENCODER) += mediacodecenc.o
OBJS-$(CONFIG_AV1_NVENC_ENCODER) += nvenc_av1.o nvenc.o
OBJS-$(CONFIG_AV1_QSV_ENCODER) += qsvenc_av1.o
OBJS-$(CONFIG_AV1_VAAPI_ENCODER) += vaapi_encode_av1.o av1_levels.o
OBJS-$(CONFIG_AV1_VULKAN_ENCODER) += vulkan_encode.o vulkan_encode_av1.o \
hw_base_encode.o av1_levels.o
OBJS-$(CONFIG_AVRN_DECODER) += avrndec.o
OBJS-$(CONFIG_AVRP_DECODER) += r210dec.o
OBJS-$(CONFIG_AVRP_ENCODER) += r210enc.o

View File

@@ -853,6 +853,7 @@ extern const FFCodec ff_av1_amf_encoder;
extern const FFCodec ff_av1_amf_decoder;
extern const FFCodec ff_av1_mf_encoder;
extern const FFCodec ff_av1_vaapi_encoder;
extern const FFCodec ff_av1_vulkan_encoder;
extern const FFCodec ff_libopenh264_encoder;
extern const FFCodec ff_libopenh264_decoder;
extern const FFCodec ff_h264_amf_encoder;

File diff suppressed because it is too large Load Diff

View File

@@ -226,6 +226,37 @@ StdVideoH265LevelIdc ff_vk_h265_level_to_vk(int level_idc)
}
}
StdVideoAV1Level ff_vk_av1_level_to_vk(int level)
{
switch (level) {
case 20: return STD_VIDEO_AV1_LEVEL_2_0;
case 21: return STD_VIDEO_AV1_LEVEL_2_1;
case 22: return STD_VIDEO_AV1_LEVEL_2_2;
case 23: return STD_VIDEO_AV1_LEVEL_2_3;
case 30: return STD_VIDEO_AV1_LEVEL_3_0;
case 31: return STD_VIDEO_AV1_LEVEL_3_1;
case 32: return STD_VIDEO_AV1_LEVEL_3_2;
case 33: return STD_VIDEO_AV1_LEVEL_3_3;
case 40: return STD_VIDEO_AV1_LEVEL_4_0;
case 41: return STD_VIDEO_AV1_LEVEL_4_1;
case 42: return STD_VIDEO_AV1_LEVEL_4_2;
case 43: return STD_VIDEO_AV1_LEVEL_4_3;
case 50: return STD_VIDEO_AV1_LEVEL_5_0;
case 51: return STD_VIDEO_AV1_LEVEL_5_1;
case 52: return STD_VIDEO_AV1_LEVEL_5_2;
case 53: return STD_VIDEO_AV1_LEVEL_5_3;
case 60: return STD_VIDEO_AV1_LEVEL_6_0;
case 61: return STD_VIDEO_AV1_LEVEL_6_1;
case 62: return STD_VIDEO_AV1_LEVEL_6_2;
case 63: return STD_VIDEO_AV1_LEVEL_6_3;
case 70: return STD_VIDEO_AV1_LEVEL_7_0;
case 71: return STD_VIDEO_AV1_LEVEL_7_1;
case 72: return STD_VIDEO_AV1_LEVEL_7_2;
default:
case 73: return STD_VIDEO_AV1_LEVEL_7_3;
}
}
StdVideoH264ProfileIdc ff_vk_h264_profile_to_vk(int profile)
{
switch (profile) {
@@ -247,6 +278,16 @@ StdVideoH265ProfileIdc ff_vk_h265_profile_to_vk(int profile)
}
}
StdVideoAV1Profile ff_vk_av1_profile_to_vk(int profile)
{
switch (profile) {
case AV_PROFILE_AV1_MAIN: return STD_VIDEO_AV1_PROFILE_MAIN;
case AV_PROFILE_AV1_HIGH: return STD_VIDEO_AV1_PROFILE_HIGH;
case AV_PROFILE_AV1_PROFESSIONAL: return STD_VIDEO_AV1_PROFILE_PROFESSIONAL;
default: return STD_VIDEO_AV1_PROFILE_INVALID;
}
}
int ff_vk_create_view(FFVulkanContext *s, FFVkVideoCommon *common,
VkImageView *view, VkImageAspectFlags *aspect,
AVVkFrame *src, VkFormat vkf, int is_dpb)

View File

@@ -71,12 +71,14 @@ int ff_vk_h265_level_to_av(StdVideoH265LevelIdc level);
StdVideoH264LevelIdc ff_vk_h264_level_to_vk(int level_idc);
StdVideoH265LevelIdc ff_vk_h265_level_to_vk(int level_idc);
StdVideoAV1Level ff_vk_av1_level_to_vk(int level);
/**
* Convert profile from/to AV to Vulkan
*/
StdVideoH264ProfileIdc ff_vk_h264_profile_to_vk(int profile);
StdVideoH265ProfileIdc ff_vk_h265_profile_to_vk(int profile);
StdVideoAV1Profile ff_vk_av1_profile_to_vk(int profile);
/**
* Creates image views for video frames.

View File

@@ -93,6 +93,9 @@ typedef struct VulkanDeviceFeatures {
#ifdef VK_KHR_video_decode_vp9
VkPhysicalDeviceVideoDecodeVP9FeaturesKHR vp9_decode;
#endif
#ifdef VK_KHR_video_encode_av1
VkPhysicalDeviceVideoEncodeAV1FeaturesKHR av1_encode;
#endif
VkPhysicalDeviceShaderObjectFeaturesEXT shader_object;
VkPhysicalDeviceCooperativeMatrixFeaturesKHR cooperative_matrix;
@@ -237,6 +240,10 @@ static void device_features_init(AVHWDeviceContext *ctx, VulkanDeviceFeatures *f
FF_VK_STRUCT_EXT(s, &feats->device, &feats->vp9_decode, FF_VK_EXT_VIDEO_DECODE_VP9,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_DECODE_VP9_FEATURES_KHR);
#endif
#ifdef VK_KHR_video_encode_av1
FF_VK_STRUCT_EXT(s, &feats->device, &feats->av1_encode, FF_VK_EXT_VIDEO_ENCODE_AV1,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_ENCODE_AV1_FEATURES_KHR);
#endif
FF_VK_STRUCT_EXT(s, &feats->device, &feats->shader_object, FF_VK_EXT_SHADER_OBJECT,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_OBJECT_FEATURES_EXT);
@@ -313,6 +320,10 @@ static void device_features_copy_needed(VulkanDeviceFeatures *dst, VulkanDeviceF
COPY_VAL(vp9_decode.videoDecodeVP9);
#endif
#ifdef VK_KHR_video_encode_av1
COPY_VAL(av1_encode.videoEncodeAV1);
#endif
COPY_VAL(shader_object.shaderObject);
COPY_VAL(cooperative_matrix.cooperativeMatrix);
@@ -660,6 +671,9 @@ static const VulkanOptExtension optional_device_exts[] = {
{ VK_KHR_VIDEO_DECODE_H265_EXTENSION_NAME, FF_VK_EXT_VIDEO_DECODE_H265 },
#ifdef VK_KHR_video_decode_vp9
{ VK_KHR_VIDEO_DECODE_VP9_EXTENSION_NAME, FF_VK_EXT_VIDEO_DECODE_VP9 },
#endif
#ifdef VK_KHR_video_encode_av1
{ VK_KHR_VIDEO_ENCODE_AV1_EXTENSION_NAME, FF_VK_EXT_VIDEO_ENCODE_AV1 },
#endif
{ VK_KHR_VIDEO_DECODE_AV1_EXTENSION_NAME, FF_VK_EXT_VIDEO_DECODE_AV1 },
};
@@ -1569,6 +1583,9 @@ static int setup_queue_families(AVHWDeviceContext *ctx, VkDeviceCreateInfo *cd)
PICK_QF(VK_QUEUE_VIDEO_DECODE_BIT_KHR, VK_VIDEO_CODEC_OPERATION_DECODE_VP9_BIT_KHR);
#endif
#ifdef VK_KHR_video_encode_av1
PICK_QF(VK_QUEUE_VIDEO_ENCODE_BIT_KHR, VK_VIDEO_CODEC_OPERATION_ENCODE_AV1_BIT_KHR);
#endif
PICK_QF(VK_QUEUE_VIDEO_DECODE_BIT_KHR, VK_VIDEO_CODEC_OPERATION_DECODE_AV1_BIT_KHR);
av_free(qf);

View File

@@ -65,6 +65,7 @@ typedef uint64_t FFVulkanExtensions;
#define FF_VK_EXT_VIDEO_ENCODE_QUEUE (1ULL << 50) /* VK_KHR_video_encode_queue */
#define FF_VK_EXT_VIDEO_ENCODE_H264 (1ULL << 51) /* VK_KHR_video_encode_h264 */
#define FF_VK_EXT_VIDEO_ENCODE_H265 (1ULL << 52) /* VK_KHR_video_encode_h265 */
#define FF_VK_EXT_VIDEO_ENCODE_AV1 (1ULL << 53) /* VK_KHR_video_encode_av1 */
#define FF_VK_EXT_PORTABILITY_SUBSET (1ULL << 62)
#define FF_VK_EXT_NO_FLAG (1ULL << 63)

View File

@@ -83,6 +83,9 @@ static inline uint64_t ff_vk_extensions_to_mask(const char * const *extensions,
{ VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME, FF_VK_EXT_PUSH_DESCRIPTOR },
#ifdef VK_KHR_shader_expect_assume
{ VK_KHR_SHADER_EXPECT_ASSUME_EXTENSION_NAME, FF_VK_EXT_EXPECT_ASSUME },
#endif
#ifdef VK_KHR_video_encode_av1
{ VK_KHR_VIDEO_ENCODE_AV1_EXTENSION_NAME, FF_VK_EXT_VIDEO_ENCODE_AV1 },
#endif
};