On 3/25/24 9:49 AM, Andrea Mastroberti wrote: > Signed-off-by: Andrea Mastroberti <10736595@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}. > + > +@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. > + > +@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. > + > +@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. >  @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 }, >  +    { "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 }, > +    { "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 }, > +    { "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 }, > + >      { 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 */ >      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; > +    if (s->alpha.strength < STRENGTH_MIN) > +        s->alpha.strength  = s->alpha.strength; > +    if (s->alpha.threshold < THRESHOLD_MIN) > +        s->alpha.threshold = s->alpha.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\n" > +           "alpha_radius:%f alpha_strength:%f alpha_threshold:%d ", >             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); >  }