Commit 92a5c7e4f5 for ffmpeg
commit 92a5c7e4f524b277d758940689c4a8d20fe4b9db
Author: Marcos Ashton Iglesias <marcosashiglesias@gmail.com>
Date: Wed Sep 30 19:37:41 2026 +0100
avfilter/vf_avgblur_vulkan: use the documented radius and edge handling
sizeX/sizeY were used as radius - 1, the normalisation ignored the
vertical radius and pixels outside the frame were read as black. Match
avgblur: use the radii, limited to half the chroma plane, and repeat the
edge pixels. Existing uses now blur one pixel more, as documented.
diff --git a/libavfilter/vf_avgblur_vulkan.c b/libavfilter/vf_avgblur_vulkan.c
index be11a76070..c198720cb6 100644
--- a/libavfilter/vf_avgblur_vulkan.c
+++ b/libavfilter/vf_avgblur_vulkan.c
@@ -20,6 +20,7 @@
#include "libavutil/random_seed.h"
#include "libavutil/opt.h"
+#include "libavutil/pixdesc.h"
#include "vulkan_filter.h"
#include "filters.h"
@@ -53,6 +54,7 @@ static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in)
AvgBlurVulkanContext *s = ctx->priv;
FFVulkanContext *vkctx = &s->vkctx;
const int planes = av_pix_fmt_count_planes(s->vkctx.output_format);
+ const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(s->vkctx.output_format);
s->qf = ff_vk_qf_find(vkctx, VK_QUEUE_COMPUTE_BIT, 0);
if (!s->qf) {
@@ -90,11 +92,13 @@ static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in)
RET(ff_vk_shader_register_exec(vkctx, &s->e, &s->shd));
s->initialized = 1;
- s->opts.filter_len[0] = s->size_x - 1;
- s->opts.filter_len[1] = s->size_y - 1;
+ /* like avgblur, at most half the chroma plane */
+ s->opts.filter_len[0] = FFMIN(s->size_x,
+ AV_CEIL_RSHIFT(vkctx->output_width, desc->log2_chroma_w) / 2);
+ s->opts.filter_len[1] = FFMIN(s->size_y,
+ AV_CEIL_RSHIFT(vkctx->output_height, desc->log2_chroma_h) / 2);
- s->opts.filter_norm[0] = s->opts.filter_len[0]*2 + 1;
- s->opts.filter_norm[0] = 1.0/(s->opts.filter_norm[0]*s->opts.filter_norm[0]);
+ s->opts.filter_norm[0] = 1.0/((s->opts.filter_len[0]*2 + 1)*(s->opts.filter_len[1]*2 + 1));
s->opts.filter_norm[1] = s->opts.filter_norm[0];
s->opts.filter_norm[2] = s->opts.filter_norm[0];
s->opts.filter_norm[3] = s->opts.filter_norm[0];
diff --git a/libavfilter/vulkan/avgblur.comp.glsl b/libavfilter/vulkan/avgblur.comp.glsl
index 4cfd4f433d..1a6f26ad07 100644
--- a/libavfilter/vulkan/avgblur.comp.glsl
+++ b/libavfilter/vulkan/avgblur.comp.glsl
@@ -54,7 +54,7 @@ void main()
for (int y = -filter_len.y; y <= filter_len.y; y++)
for (int x = -filter_len.x; x <= filter_len.x; x++)
sum += imageLoad(input_img[nonuniformEXT(gl_LocalInvocationID.z)],
- pos + ivec2(x, y));
+ clamp(pos + ivec2(x, y), ivec2(0), size - 1));
imageStore(output_img[nonuniformEXT(gl_LocalInvocationID.z)],
pos, sum * filter_norm);