diff --git a/doc/filters.texi b/doc/filters.texi index 3febd2e3db..48b93f5315 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -4925,30 +4925,40 @@ expressed in the form "[@var{c0} @var{c1} @var{c2} @var{c3}]" Blur the input video without impacting the outlines. -The filter accepts the following parameters: +This filter accepts parameters as a list of @var{key}=@var{value} pairs, +separated by ":". + +If the key of the first options is omitted, the arguments are +interpreted according to the syntax: @var{luma_radius}:@var{luma_strength}:@var{luma_threshold}[:@var{chroma_radius}:@var{chroma_strength}:@var{chroma_threshold}] -Parameters prefixed by @var{luma} indicate that they work on the -luminance of the pixels whereas parameters prefixed by @var{chroma} -refer to the chrominance of the pixels. +A description of the accepted options follows. -If the chroma parameters are not set, the luma parameters are used for -either the luminance and the chrominance of the pixels. +@table @option +@item luma_radius, lr +@item chroma_radius, cr +Set the luma/chroma 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. -@var{luma_radius} or @var{chroma_radius} 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). +@item luma_strength, ls +@item chroma_strength, cs +Set the luma/chroma 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. -@var{luma_strength} or @var{chroma_strength} 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. +@item luma_threshold, lt +@item chroma_threshold, ct +Set the luma/chroma 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 -@var{luma_threshold} or @var{chroma_threshold} must be an integer in -the range [-30,30] that is used as a coefficient to determine whether -a pixel should be blurred or not. 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. +If a chroma option is not explicitly set, the corresponding luma value +is set. @section stereo3d diff --git a/libavfilter/version.h b/libavfilter/version.h index 598397b958..042257d4c8 100644 --- a/libavfilter/version.h +++ b/libavfilter/version.h @@ -30,7 +30,7 @@ #define LIBAVFILTER_VERSION_MAJOR 3 #define LIBAVFILTER_VERSION_MINOR 44 -#define LIBAVFILTER_VERSION_MICRO 100 +#define LIBAVFILTER_VERSION_MICRO 101 #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ LIBAVFILTER_VERSION_MINOR, \ diff --git a/libavfilter/vf_smartblur.c b/libavfilter/vf_smartblur.c index 7de1cd3ae6..f31cb8a066 100644 --- a/libavfilter/vf_smartblur.c +++ b/libavfilter/vf_smartblur.c @@ -25,6 +25,7 @@ * Ported from MPlayer libmpcodecs/vf_smartblur.c by Michael Niedermayer. */ +#include "libavutil/opt.h" #include "libavutil/pixdesc.h" #include "libswscale/swscale.h" @@ -50,6 +51,7 @@ typedef struct { } FilterParam; typedef struct { + const AVClass *class; FilterParam luma; FilterParam chroma; int hsub; @@ -57,63 +59,63 @@ typedef struct { unsigned int sws_flags; } SmartblurContext; -#define CHECK_PARAM(param, name, min, max, format, ret) \ - if (param < min || param > max) { \ - av_log(ctx, AV_LOG_ERROR, \ - "Invalid " #name " value " #format ": " \ - "must be included between range " #format " and " #format "\n",\ - param, min, max); \ - ret = AVERROR(EINVAL); \ - } +#define OFFSET(x) offsetof(SmartblurContext, x) +#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM + +static const AVOption smartblur_options[] = { + { "luma_radius", "set luma radius", OFFSET(luma.radius), AV_OPT_TYPE_FLOAT, {.dbl=1.0}, RADIUS_MIN, RADIUS_MAX, .flags=FLAGS }, + { "lr" , "set luma radius", OFFSET(luma.radius), AV_OPT_TYPE_FLOAT, {.dbl=1.0}, RADIUS_MIN, RADIUS_MAX, .flags=FLAGS }, + { "luma_strength", "set luma strength", OFFSET(luma.strength), AV_OPT_TYPE_FLOAT, {.dbl=1.0}, STRENGTH_MIN, STRENGTH_MAX, .flags=FLAGS }, + { "ls", "set luma strength", OFFSET(luma.strength), AV_OPT_TYPE_FLOAT, {.dbl=1.0}, STRENGTH_MIN, STRENGTH_MAX, .flags=FLAGS }, + { "luma_threshold", "set luma threshold", OFFSET(luma.threshold), AV_OPT_TYPE_INT, {.i64=0}, THRESHOLD_MIN, THRESHOLD_MAX, .flags=FLAGS }, + { "lt", "set luma threshold", OFFSET(luma.threshold), AV_OPT_TYPE_INT, {.i64=0}, THRESHOLD_MIN, THRESHOLD_MAX, .flags=FLAGS }, + + { "chroma_radius", "set chroma radius", OFFSET(chroma.radius), AV_OPT_TYPE_FLOAT, {.dbl=RADIUS_MIN-1}, RADIUS_MIN-1, RADIUS_MAX, .flags=FLAGS }, + { "cr", "set chroma radius", OFFSET(chroma.radius), AV_OPT_TYPE_FLOAT, {.dbl=RADIUS_MIN-1}, RADIUS_MIN-1, RADIUS_MAX, .flags=FLAGS }, + { "chroma_strength", "set chroma strength", OFFSET(chroma.strength), AV_OPT_TYPE_FLOAT, {.dbl=STRENGTH_MIN-1}, STRENGTH_MIN-1, STRENGTH_MAX, .flags=FLAGS }, + { "cs", "set chroma strength", OFFSET(chroma.strength), AV_OPT_TYPE_FLOAT, {.dbl=STRENGTH_MIN-1}, STRENGTH_MIN-1, STRENGTH_MAX, .flags=FLAGS }, + { "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 }, + + { NULL } +}; + +AVFILTER_DEFINE_CLASS(smartblur); static av_cold int init(AVFilterContext *ctx, const char *args) { SmartblurContext *sblur = ctx->priv; - int n = 0, ret = 0; - float lradius, lstrength, cradius, cstrength; - int lthreshold, cthreshold; + int ret; + static const char *shorthand[] = { + "luma_radius", "luma_strength", "luma_threshold", + "chroma_radius", "chroma_strength", "chroma_threshold", + NULL + }; - if (args) - n = sscanf(args, "%f:%f:%d:%f:%f:%d", - &lradius, &lstrength, <hreshold, - &cradius, &cstrength, &cthreshold); + sblur->class = &smartblur_class; + av_opt_set_defaults(sblur); - if (n != 3 && n != 6) { - av_log(ctx, AV_LOG_ERROR, - "Incorrect number of parameters or invalid syntax: " - "must be luma_radius:luma_strength:luma_threshold" - "[:chroma_radius:chroma_strength:chroma_threshold]\n"); - return AVERROR(EINVAL); - } + if ((ret = av_opt_set_from_string(sblur, args, shorthand, "=", ":")) < 0) + return ret; - sblur->luma.radius = lradius; - sblur->luma.strength = lstrength; - sblur->luma.threshold = lthreshold; - - if (n == 3) { - sblur->chroma.radius = sblur->luma.radius; + /* make chroma default to luma values, if not explicitly set */ + if (sblur->chroma.radius < RADIUS_MIN) + sblur->chroma.radius = sblur->luma.radius; + if (sblur->chroma.strength < STRENGTH_MIN) sblur->chroma.strength = sblur->luma.strength; + if (sblur->chroma.threshold < THRESHOLD_MIN) sblur->chroma.threshold = sblur->luma.threshold; - } else { - sblur->chroma.radius = cradius; - sblur->chroma.strength = cstrength; - sblur->chroma.threshold = cthreshold; - } sblur->luma.quality = sblur->chroma.quality = 3.0; sblur->sws_flags = SWS_BICUBIC; - CHECK_PARAM(lradius, luma radius, RADIUS_MIN, RADIUS_MAX, %0.1f, ret) - CHECK_PARAM(lstrength, luma strength, STRENGTH_MIN, STRENGTH_MAX, %0.1f, ret) - CHECK_PARAM(lthreshold, luma threshold, THRESHOLD_MIN, THRESHOLD_MAX, %d, ret) + av_log(ctx, AV_LOG_VERBOSE, + "luma_radius:%f luma_strength:%f luma_threshold:%d " + "chroma_radius:%f chroma_strength:%f chroma_threshold:%d ", + sblur->luma.radius, sblur->luma.strength, sblur->luma.threshold, + sblur->chroma.radius, sblur->chroma.strength, sblur->chroma.threshold); - if (n != 3) { - CHECK_PARAM(sblur->chroma.radius, chroma radius, RADIUS_MIN, RADIUS_MAX, %0.1f, ret) - CHECK_PARAM(sblur->chroma.strength, chroma strength, STRENGTH_MIN, STRENGTH_MAX, %0.1f, ret) - CHECK_PARAM(sblur->chroma.threshold, chroma threshold, THRESHOLD_MIN,THRESHOLD_MAX, %d, ret) - } - - return ret; + return 0; } static av_cold void uninit(AVFilterContext *ctx) @@ -122,6 +124,7 @@ static av_cold void uninit(AVFilterContext *ctx) sws_freeContext(sblur->luma.filter_context); sws_freeContext(sblur->chroma.filter_context); + av_opt_free(sblur); } static int query_formats(AVFilterContext *ctx) @@ -310,4 +313,5 @@ AVFilter avfilter_vf_smartblur = { .query_formats = query_formats, .inputs = smartblur_inputs, .outputs = smartblur_outputs, + .priv_class = &smartblur_class, };