[FFmpeg-devel] [PATCH] Added alpha layer support for smartblur
Cosmin Stejerean
cosmin at cosmin.at
Thu May 2 02:19:18 EEST 2024
> On Mar 25, 2024, at 1:49 AM, Andrea Mastroberti via ffmpeg-devel <ffmpeg-devel at ffmpeg.org> wrote:
>
> Signed-off-by: Andrea Mastroberti <10736595 at polimi.it>
> ---
> doc/filters.texi | 20 ++++++++++++++++-
> libavfilter/version.h | 2 +-
> libavfilter/vf_smartblur.c | 44 ++++++++++++++++++++++++++++++--------
> 3 files changed, 55 insertions(+), 11 deletions(-)
>
> diff --git a/doc/filters.texi b/doc/filters.texi
> index 913365671d..30b3627724 100644
> --- a/doc/filters.texi
> +++ b/doc/filters.texi
> @@ -22688,9 +22688,27 @@ whether a pixel should be blurred or not. The option value must be an
> integer in the range [-30,30]. A value of 0 will filter all the image,
> a value included in [0,30] will filter flat areas and a value included
> in [-30,0] will filter edges. Default value is @option{luma_threshold}.
> +
> + at item alpha_radius, ar
> +Set the alpha radius. The option value must be a float number in
> +the range [0.1,5.0] that specifies the variance of the gaussian filter
> +used to blur the image (slower if larger). Default value is 1.0.
Default value should be @option{luma_radius}.
> +
> + at item alpha_strength, as
> +Set the alpha strength. The option value must be a float number
> +in the range [-1.0,1.0] that configures the blurring. A value included
> +in [0.0,1.0] will blur the image whereas a value included in
> +[-1.0,0.0] will sharpen the image. Default value is 1.0.
Default value should be @option{luma_strength}.
> +
> + at item alpha_threshold, at
> +Set the alpha threshold used as a coefficient to determine
> +whether a pixel should be blurred or not. The option value must be an
> +integer in the range [-30,30]. A value of 0 will filter all the image,
> +a value included in [0,30] will filter flat areas and a value included
> +in [-30,0] will filter edges. Default value is 0.
Default value should be @option{luma_threshold}.
> @end table
> -If a chroma option is not explicitly set, the corresponding luma value
> +If a chroma or alpha option is not explicitly set, the corresponding luma value
> is set.
> @section sobel
> diff --git a/libavfilter/version.h b/libavfilter/version.h
> index d5a6bc143a..f01b3f8e91 100644
> --- a/libavfilter/version.h
> +++ b/libavfilter/version.h
> @@ -32,7 +32,7 @@
> #include "version_major.h"
> #define LIBAVFILTER_VERSION_MINOR 0
> -#define LIBAVFILTER_VERSION_MICRO 100
> +#define LIBAVFILTER_VERSION_MICRO 101
> #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \
> diff --git a/libavfilter/vf_smartblur.c b/libavfilter/vf_smartblur.c
> index ae0ec05b2d..bc377d0b92 100644
> --- a/libavfilter/vf_smartblur.c
> +++ b/libavfilter/vf_smartblur.c
> @@ -54,6 +54,7 @@ typedef struct SmartblurContext {
> const AVClass *class;
> FilterParam luma;
> FilterParam chroma;
> + FilterParam alpha;
> int hsub;
> int vsub;
> unsigned int sws_flags;
> @@ -77,6 +78,13 @@ static const AVOption smartblur_options[] = {
> { "chroma_threshold", "set chroma threshold", OFFSET(chroma.threshold), AV_OPT_TYPE_INT, {.i64=THRESHOLD_MIN-1}, THRESHOLD_MIN-1, THRESHOLD_MAX, .flags=FLAGS },
> { "ct", "set chroma threshold", OFFSET(chroma.threshold), AV_OPT_TYPE_INT, {.i64=THRESHOLD_MIN-1}, THRESHOLD_MIN-1, THRESHOLD_MAX, .flags=FLAGS },
Probably add a line break in here for visual separation as there is between chroma and luma parameters.
> + { "alpha_radius", "set alpha radius", OFFSET(alpha.radius), AV_OPT_TYPE_FLOAT, {.dbl=1.0}, RADIUS_MIN, RADIUS_MAX, .flags=FLAGS },
> + { "ar" , "set alpha radius", OFFSET(alpha.radius), AV_OPT_TYPE_FLOAT, {.dbl=1.0}, RADIUS_MIN, RADIUS_MAX, .flags=FLAGS },
The default value for both of those should be RADIUS_MIN-1 not 1.0, and the minimum value RADIUS_MIN-1.
> + { "alpha_strength", "set alpha strength", OFFSET(alpha.strength), AV_OPT_TYPE_FLOAT, {.dbl=1.0}, STRENGTH_MIN, STRENGTH_MAX, .flags=FLAGS },
> + { "as", "set alpha strength", OFFSET(alpha.strength), AV_OPT_TYPE_FLOAT, {.dbl=1.0}, STRENGTH_MIN, STRENGTH_MAX, .flags=FLAGS },
The default value should be STRENGTH_MIN-1, likewise for the minimum value.
> + { "alpha_threshold", "set alpha threshold", OFFSET(alpha.threshold), AV_OPT_TYPE_INT, {.i64=0}, THRESHOLD_MIN, THRESHOLD_MAX, .flags=FLAGS },
> + { "at", "set alpha threshold", OFFSET(alpha.threshold), AV_OPT_TYPE_INT, {.i64=0}, THRESHOLD_MIN, THRESHOLD_MAX, .flags=FLAGS },
The default value should be THRESHOLD_MIN-1, likewise for the minimum value.
> +
> { NULL }
> };
> @@ -86,7 +94,7 @@ static av_cold int init(AVFilterContext *ctx)
> {
> SmartblurContext *s = ctx->priv;
> - /* make chroma default to luma values, if not explicitly set */
> + /* make chroma and alpha default to luma values, if not explicitly set */
Rather than change this comment I think you can add a similar comment above the alpha defaulting below
> if (s->chroma.radius < RADIUS_MIN)
> s->chroma.radius = s->luma.radius;
> if (s->chroma.strength < STRENGTH_MIN)
> @@ -94,15 +102,23 @@ static av_cold int init(AVFilterContext *ctx)
> if (s->chroma.threshold < THRESHOLD_MIN)
> s->chroma.threshold = s->luma.threshold;
> - s->luma.quality = s->chroma.quality = 3.0;
> + if (s->alpha.radius < RADIUS_MIN)
> + s->alpha.radius = s->alpha.radius;
s->alpha.radius = s->luma.radius
> + if (s->alpha.strength < STRENGTH_MIN)
> + s->alpha.strength = s->alpha.strength;
same here, default from luma
> + if (s->alpha.threshold < THRESHOLD_MIN)
> + s->alpha.threshold = s->alpha.threshold;
and also here
> +
> + s->luma.quality = s->chroma.quality = s->alpha.quality = 3.0;
> s->sws_flags = SWS_BICUBIC;
> av_log(ctx, AV_LOG_VERBOSE,
> "luma_radius:%f luma_strength:%f luma_threshold:%d "
> - "chroma_radius:%f chroma_strength:%f chroma_threshold:%d\n",
> + "chroma_radius:%f chroma_strength:%f chroma_threshold:%d\n"
> + "alpha_radius:%f alpha_strength:%f alpha_threshold:%d ",
Missing a \n on that last line, also looks like formatting is slightly off on the chroma_radius line, that line should be unchanged here
> s->luma.radius, s->luma.strength, s->luma.threshold,
> - s->chroma.radius, s->chroma.strength, s->chroma.threshold);
> -
> + s->chroma.radius, s->chroma.strength, s->chroma.threshold,
> + s->alpha.radius, s->alpha.strength, s->alpha.threshold);
> return 0;
> }
> @@ -112,13 +128,15 @@ static av_cold void uninit(AVFilterContext *ctx)
> sws_freeContext(s->luma.filter_context);
> sws_freeContext(s->chroma.filter_context);
> + sws_freeContext(s->alpha.filter_context);
> }
> static const enum AVPixelFormat pix_fmts[] = {
> - AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV422P,
> - AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV411P,
> - AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUV440P,
> - AV_PIX_FMT_GRAY8,
> + AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUVA444P,
> + AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUVA422P,
> + AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUVA420P,
> + AV_PIX_FMT_YUV411P, AV_PIX_FMT_YUV410P,
> + AV_PIX_FMT_YUV440P, AV_PIX_FMT_GRAY8,
> AV_PIX_FMT_NONE
> };
> @@ -162,6 +180,7 @@ static int config_props(AVFilterLink *inlink)
> AV_CEIL_RSHIFT(inlink->w, s->hsub),
> AV_CEIL_RSHIFT(inlink->h, s->vsub),
> s->sws_flags);
> + alloc_sws_context(&s->alpha, inlink->w, inlink->h, s->sws_flags);
> return 0;
> }
> @@ -261,6 +280,13 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *inpic)
> s->chroma.filter_context);
> }
> + if (inpic->data[3]) {
> + blur(outpic->data[3], outpic->linesize[3],
> + inpic->data[3], inpic->linesize[3],
> + inlink->w, inlink->h, s->alpha.threshold,
> + s->alpha.filter_context);
> + }
> +
> av_frame_free(&inpic);
> return ff_filter_frame(outlink, outpic);
> }
> --
> 2.44.0
>
More information about the ffmpeg-devel
mailing list