From bdfb0e4da414c0ff4c663fa077b15730b44482df Mon Sep 17 00:00:00 2001 From: Wu Jianhua Date: Fri, 26 Nov 2021 17:10:57 +0800 Subject: [PATCH] avfilter: add a flip_vulkan filter This filter flips the input video both horizontally and vertically in one compute pipeline, and it's no need to use two pipelines for hflip_vulkan,vflip_vulkan anymore. Signed-off-by: Wu Jianhua --- configure | 1 + libavfilter/allfilters.c | 1 + libavfilter/vf_flip_vulkan.c | 61 +++++++++++++++++++++++++++++------- 3 files changed, 51 insertions(+), 12 deletions(-) diff --git a/configure b/configure index aa94c39419..a98a18abaa 100755 --- a/configure +++ b/configure @@ -3631,6 +3631,7 @@ fftdnoiz_filter_select="fft" find_rect_filter_deps="avcodec avformat gpl" firequalizer_filter_deps="avcodec" firequalizer_filter_select="rdft" +flip_vulkan_filter_deps="vulkan spirv_compiler" flite_filter_deps="libflite" framerate_filter_select="scene_sad" freezedetect_filter_select="scene_sad" diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c index c5c0e9b28b..2f91562aa2 100644 --- a/libavfilter/allfilters.c +++ b/libavfilter/allfilters.c @@ -265,6 +265,7 @@ extern const AVFilter ff_vf_fieldmatch; extern const AVFilter ff_vf_fieldorder; extern const AVFilter ff_vf_fillborders; extern const AVFilter ff_vf_find_rect; +extern const AVFilter ff_vf_flip_vulkan; extern const AVFilter ff_vf_floodfill; extern const AVFilter ff_vf_format; extern const AVFilter ff_vf_fps; diff --git a/libavfilter/vf_flip_vulkan.c b/libavfilter/vf_flip_vulkan.c index e9e04db91b..0223786ef1 100644 --- a/libavfilter/vf_flip_vulkan.c +++ b/libavfilter/vf_flip_vulkan.c @@ -26,7 +26,8 @@ enum FlipType { FLIP_VERTICAL, - FLIP_HORIZONTAL + FLIP_HORIZONTAL, + FLIP_BOTH }; typedef struct FlipVulkanContext { @@ -104,6 +105,9 @@ static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in, enum FlipType case FLIP_VERTICAL: GLSLF(2, vec4 res = texture(input_image[%i], ivec2(pos.x, size.y - pos.y)); ,i); break; + case FLIP_BOTH: + GLSLF(2, vec4 res = texture(input_image[%i], ivec2(size.xy - pos.xy));, i); + break; default: GLSLF(2, vec4 res = texture(input_image[%i], pos); ,i); break; @@ -226,7 +230,7 @@ fail: return err; } -static int flip_vulkan_filter_frame(AVFilterLink *link, AVFrame *in, enum FlipType type) +static int filter_frame(AVFilterLink *link, AVFrame *in, enum FlipType type) { int err; AVFrame *out = NULL; @@ -259,14 +263,27 @@ fail: static int hflip_vulkan_filter_frame(AVFilterLink *link, AVFrame *in) { - return flip_vulkan_filter_frame(link, in, FLIP_HORIZONTAL); + return filter_frame(link, in, FLIP_HORIZONTAL); } static int vflip_vulkan_filter_frame(AVFilterLink *link, AVFrame *in) { - return flip_vulkan_filter_frame(link, in, FLIP_VERTICAL); + return filter_frame(link, in, FLIP_VERTICAL); } +static int flip_vulkan_filter_frame(AVFilterLink *link, AVFrame *in) +{ + return filter_frame(link, in, FLIP_BOTH); +} + +static const AVFilterPad flip_vulkan_outputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_VIDEO, + .config_props = &ff_vk_filter_config_output, + } +}; + static const AVOption hflip_vulkan_options[] = { { NULL }, }; @@ -282,14 +299,6 @@ static const AVFilterPad hflip_vulkan_inputs[] = { } }; -static const AVFilterPad flip_vulkan_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .config_props = &ff_vk_filter_config_output, - } -}; - const AVFilter ff_vf_hflip_vulkan = { .name = "hflip_vulkan", .description = NULL_IF_CONFIG_SMALL("Horizontally flip the input video in Vulkan"), @@ -330,3 +339,31 @@ const AVFilter ff_vf_vflip_vulkan = { .priv_class = &vflip_vulkan_class, .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE, }; + +static const AVOption flip_vulkan_options[] = { + { NULL }, +}; + +AVFILTER_DEFINE_CLASS(flip_vulkan); + +static const AVFilterPad flip_vulkan_inputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_VIDEO, + .filter_frame = &flip_vulkan_filter_frame, + .config_props = &ff_vk_filter_config_input, + } +}; + +const AVFilter ff_vf_flip_vulkan = { + .name = "flip_vulkan", + .description = NULL_IF_CONFIG_SMALL("Flip both horizontally and vertically"), + .priv_size = sizeof(FlipVulkanContext), + .init = &ff_vk_filter_init, + .uninit = &flip_vulkan_uninit, + FILTER_INPUTS(flip_vulkan_inputs), + FILTER_OUTPUTS(flip_vulkan_outputs), + FILTER_SINGLE_PIXFMT(AV_PIX_FMT_VULKAN), + .priv_class = &flip_vulkan_class, + .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE, +};