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.
Showing the changes to libavfilter (2 of 3 files). Show all
Unified · Split
| @@ -265,6 +265,7 @@ extern const AVFilter ff_vf_fieldmatch; · 264 unmodified lines | |||
| 265 | extern const AVFilter ff_vf_fieldorder; | 265 | extern const AVFilter ff_vf_fieldorder; |
| 266 | extern const AVFilter ff_vf_fillborders; | 266 | extern const AVFilter ff_vf_fillborders; |
| 267 | extern const AVFilter ff_vf_find_rect; | 267 | extern const AVFilter ff_vf_find_rect; |
| 268 | extern const AVFilter ff_vf_flip_vulkan; | ||
| 268 | extern const AVFilter ff_vf_floodfill; | 269 | extern const AVFilter ff_vf_floodfill; |
| 269 | extern const AVFilter ff_vf_format; | 270 | extern const AVFilter ff_vf_format; |
| 270 | extern const AVFilter ff_vf_fps; | 271 | extern const AVFilter ff_vf_fps; |
| @@ -26,7 +26,8 @@ · 25 unmodified lines | |||
| 26 | 26 | ||
| 27 | enum FlipType { | 27 | enum FlipType { |
| 28 | FLIP_VERTICAL, | 28 | FLIP_VERTICAL, |
| 29 | FLIP_HORIZONTAL | 29 | FLIP_HORIZONTAL, |
| 30 | FLIP_BOTH | ||
| 30 | }; | 31 | }; |
| 31 | 32 | ||
| 32 | typedef struct FlipVulkanContext { | 33 | typedef struct FlipVulkanContext { |
| @@ -104,6 +105,9 @@ static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in, enum FlipType · 71 unmodified lines | |||
| 104 | case FLIP_VERTICAL: | 105 | case FLIP_VERTICAL: |
| 105 | GLSLF(2, vec4 res = texture(input_image[%i], ivec2(pos.x, size.y - pos.y)); ,i); | 106 | GLSLF(2, vec4 res = texture(input_image[%i], ivec2(pos.x, size.y - pos.y)); ,i); |
| 106 | break; | 107 | break; |
| 108 | case FLIP_BOTH: | ||
| 109 | GLSLF(2, vec4 res = texture(input_image[%i], ivec2(size.xy - pos.xy));, i); | ||
| 110 | break; | ||
| 107 | default: | 111 | default: |
| 108 | GLSLF(2, vec4 res = texture(input_image[%i], pos); ,i); | 112 | GLSLF(2, vec4 res = texture(input_image[%i], pos); ,i); |
| 109 | break; | 113 | break; |
| @@ -226,7 +230,7 @@ fail: · 116 unmodified lines | |||
| 226 | return err; | 230 | return err; |
| 227 | } | 231 | } |
| 228 | 232 | ||
| 229 | static int flip_vulkan_filter_frame(AVFilterLink *link, AVFrame *in, enum FlipType type) | 233 | static int filter_frame(AVFilterLink *link, AVFrame *in, enum FlipType type) |
| 230 | { | 234 | { |
| 231 | int err; | 235 | int err; |
| 232 | AVFrame *out = NULL; | 236 | AVFrame *out = NULL; |
| @@ -259,14 +263,27 @@ fail: · 26 unmodified lines | |||
| 259 | 263 | ||
| 260 | static int hflip_vulkan_filter_frame(AVFilterLink *link, AVFrame *in) | 264 | static int hflip_vulkan_filter_frame(AVFilterLink *link, AVFrame *in) |
| 261 | { | 265 | { |
| 262 | return flip_vulkan_filter_frame(link, in, FLIP_HORIZONTAL); | 266 | return filter_frame(link, in, FLIP_HORIZONTAL); |
| 263 | } | 267 | } |
| 264 | 268 | ||
| 265 | static int vflip_vulkan_filter_frame(AVFilterLink *link, AVFrame *in) | 269 | static int vflip_vulkan_filter_frame(AVFilterLink *link, AVFrame *in) |
| 266 | { | 270 | { |
| 267 | return flip_vulkan_filter_frame(link, in, FLIP_VERTICAL); | 271 | return filter_frame(link, in, FLIP_VERTICAL); |
| 268 | } | 272 | } |
| 269 | 273 | ||
| 274 | static int flip_vulkan_filter_frame(AVFilterLink *link, AVFrame *in) | ||
| 275 | { | ||
| 276 | return filter_frame(link, in, FLIP_BOTH); | ||
| 277 | } | ||
| 278 | |||
| 279 | static const AVFilterPad flip_vulkan_outputs[] = { | ||
| 280 | { | ||
| 281 | .name = "default", | ||
| 282 | .type = AVMEDIA_TYPE_VIDEO, | ||
| 283 | .config_props = &ff_vk_filter_config_output, | ||
| 284 | } | ||
| 285 | }; | ||
| 286 | |||
| 270 | static const AVOption hflip_vulkan_options[] = { | 287 | static const AVOption hflip_vulkan_options[] = { |
| 271 | { NULL }, | 288 | { NULL }, |
| 272 | }; | 289 | }; |
| @@ -282,14 +299,6 @@ static const AVFilterPad hflip_vulkan_inputs[] = { · 9 unmodified lines | |||
| 282 | } | 299 | } |
| 283 | }; | 300 | }; |
| 284 | 301 | ||
| 285 | static const AVFilterPad flip_vulkan_outputs[] = { | ||
| 286 | { | ||
| 287 | .name = "default", | ||
| 288 | .type = AVMEDIA_TYPE_VIDEO, | ||
| 289 | .config_props = &ff_vk_filter_config_output, | ||
| 290 | } | ||
| 291 | }; | ||
| 292 | |||
| 293 | const AVFilter ff_vf_hflip_vulkan = { | 302 | const AVFilter ff_vf_hflip_vulkan = { |
| 294 | .name = "hflip_vulkan", | 303 | .name = "hflip_vulkan", |
| 295 | .description = NULL_IF_CONFIG_SMALL("Horizontally flip the input video in Vulkan"), | 304 | .description = NULL_IF_CONFIG_SMALL("Horizontally flip the input video in Vulkan"), |
| @@ -330,3 +339,31 @@ const AVFilter ff_vf_vflip_vulkan = { · 34 unmodified lines | |||
| 330 | .priv_class = &vflip_vulkan_class, | 339 | .priv_class = &vflip_vulkan_class, |
| 331 | .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE, | 340 | .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE, |
| 332 | }; | 341 | }; |
| 342 | |||
| 343 | static const AVOption flip_vulkan_options[] = { | ||
| 344 | { NULL }, | ||
| 345 | }; | ||
| 346 | |||
| 347 | AVFILTER_DEFINE_CLASS(flip_vulkan); | ||
| 348 | |||
| 349 | static const AVFilterPad flip_vulkan_inputs[] = { | ||
| 350 | { | ||
| 351 | .name = "default", | ||
| 352 | .type = AVMEDIA_TYPE_VIDEO, | ||
| 353 | .filter_frame = &flip_vulkan_filter_frame, | ||
| 354 | .config_props = &ff_vk_filter_config_input, | ||
| 355 | } | ||
| 356 | }; | ||
| 357 | |||
| 358 | const AVFilter ff_vf_flip_vulkan = { | ||
| 359 | .name = "flip_vulkan", | ||
| 360 | .description = NULL_IF_CONFIG_SMALL("Flip both horizontally and vertically"), | ||
| 361 | .priv_size = sizeof(FlipVulkanContext), | ||
| 362 | .init = &ff_vk_filter_init, | ||
| 363 | .uninit = &flip_vulkan_uninit, | ||
| 364 | FILTER_INPUTS(flip_vulkan_inputs), | ||
| 365 | FILTER_OUTPUTS(flip_vulkan_outputs), | ||
| 366 | FILTER_SINGLE_PIXFMT(AV_PIX_FMT_VULKAN), | ||
| 367 | .priv_class = &flip_vulkan_class, | ||
| 368 | .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE, | ||
| 369 | }; | ||