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 <jianhua.wu@intel.com>
This commit is contained in:
Wu Jianhua 2021-11-26 17:10:57 +08:00 committed by Lynne
parent fc9a686688
commit bdfb0e4da4
3 changed files with 51 additions and 12 deletions

1
configure vendored
View File

@ -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"

View File

@ -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;

View File

@ -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,
};