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 | 265 | extern const AVFilter ff_vf_fieldorder; |
| 266 | 266 | extern const AVFilter ff_vf_fillborders; |
| 267 | 267 | extern const AVFilter ff_vf_find_rect; |
| 268 | +extern const AVFilter ff_vf_flip_vulkan; | |
| 268 | 269 | extern const AVFilter ff_vf_floodfill; |
| 269 | 270 | extern const AVFilter ff_vf_format; |
| 270 | 271 | extern const AVFilter ff_vf_fps; |
| @@ -26,7 +26,8 @@ · 25 unmodified lines | ||
| 26 | 26 | |
| 27 | 27 | enum FlipType { |
| 28 | 28 | FLIP_VERTICAL, |
| 29 | − FLIP_HORIZONTAL | |
| 29 | + FLIP_HORIZONTAL, | |
| 30 | + FLIP_BOTH | |
| 30 | 31 | }; |
| 31 | 32 | |
| 32 | 33 | typedef struct FlipVulkanContext { |
| @@ -104,6 +105,9 @@ static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in, enum FlipType · 71 unmodified lines | ||
| 104 | 105 | case FLIP_VERTICAL: |
| 105 | 106 | GLSLF(2, vec4 res = texture(input_image[%i], ivec2(pos.x, size.y - pos.y)); ,i); |
| 106 | 107 | break; |
| 108 | + case FLIP_BOTH: | |
| 109 | + GLSLF(2, vec4 res = texture(input_image[%i], ivec2(size.xy - pos.xy));, i); | |
| 110 | + break; | |
| 107 | 111 | default: |
| 108 | 112 | GLSLF(2, vec4 res = texture(input_image[%i], pos); ,i); |
| 109 | 113 | break; |
| @@ -226,7 +230,7 @@ fail: · 116 unmodified lines | ||
| 226 | 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 | 235 | int err; |
| 232 | 236 | AVFrame *out = NULL; |
| @@ -259,14 +263,27 @@ fail: · 26 unmodified lines | ||
| 259 | 263 | |
| 260 | 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 | 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 | 287 | static const AVOption hflip_vulkan_options[] = { |
| 271 | 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 | 302 | const AVFilter ff_vf_hflip_vulkan = { |
| 294 | 303 | .name = "hflip_vulkan", |
| 295 | 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 | 339 | .priv_class = &vflip_vulkan_class, |
| 331 | 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 | +}; | |