From 8b62312d794ecb66cc1a8dbe4933fca0d725057b Mon Sep 17 00:00:00 2001 From: Andrea Mastroberti <10736595@polimi.it> Date: Fri, 17 May 2024 00:29:01 +0200 Subject: [PATCH] avfilter/smartblur: Added alpha layer support --- doc/filters.texi | 20 +++++++++++++++++- libavfilter/version.h | 3 ++- libavfilter/vf_smartblur.c | 43 +++++++++++++++++++++++++++++++------- 3 files changed, 56 insertions(+), 10 deletions(-) diff --git a/doc/filters.texi b/doc/filters.texi index 8230661261..f5bf475d13 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -22653,9 +22653,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}. + +@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 @option{luma_radius}. + +@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 @option{luma_strength}. + +@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 @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 408c700767..ba0c6b3862 100644 --- a/libavfilter/version.h +++ b/libavfilter/version.h @@ -31,8 +31,9 @@ #include "version_major.h" + #define LIBAVFILTER_VERSION_MINOR 2 -#define LIBAVFILTER_VERSION_MICRO 101 +#define LIBAVFILTER_VERSION_MICRO 102 #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ diff --git a/libavfilter/vf_smartblur.c b/libavfilter/vf_smartblur.c index ae0ec05b2d..dbbb74339d 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 }, + { "alpha_radius", "set alpha radius", OFFSET(alpha.radius), AV_OPT_TYPE_FLOAT, {.dbl=RADIUS_MIN-1}, RADIUS_MIN-1, RADIUS_MAX, .flags=FLAGS }, + { "ar" , "set alpha radius", OFFSET(alpha.radius), AV_OPT_TYPE_FLOAT, {.dbl=RADIUS_MIN-1}, RADIUS_MIN-1, RADIUS_MAX, .flags=FLAGS }, + { "alpha_strength", "set alpha strength", OFFSET(alpha.strength), AV_OPT_TYPE_FLOAT, {.dbl=STRENGTH_MIN-1}, STRENGTH_MIN-1, STRENGTH_MAX, .flags=FLAGS }, + { "as", "set alpha strength", OFFSET(alpha.strength), AV_OPT_TYPE_FLOAT, {.dbl=STRENGTH_MIN-1}, STRENGTH_MIN-1, STRENGTH_MAX, .flags=FLAGS }, + { "alpha_threshold", "set alpha threshold", OFFSET(alpha.threshold), AV_OPT_TYPE_INT, {.i64=THRESHOLD_MIN-1}, THRESHOLD_MIN-1, THRESHOLD_MAX, .flags=FLAGS }, + { "at", "set alpha threshold", OFFSET(alpha.threshold), AV_OPT_TYPE_INT, {.i64=THRESHOLD_MIN-1}, THRESHOLD_MIN-1, THRESHOLD_MAX, .flags=FLAGS }, + { NULL } }; @@ -94,15 +102,24 @@ 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; + /* make alpha default to luma values, if not explicitly set */ + if (s->alpha.radius < RADIUS_MIN) + s->alpha.radius = s->luma.radius; + if (s->alpha.strength < STRENGTH_MIN) + s->alpha.strength = s->luma.strength; + if (s->alpha.threshold < THRESHOLD_MIN) + s->alpha.threshold = s->luma.threshold; + + 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 " + "alpha_radius:%f alpha_strength:%f alpha_threshold:%d\n", 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 +129,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 +181,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 +281,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.45.1