... | ... |
@@ -1890,17 +1890,30 @@ blend=all_expr='if(eq(mod(X,2),mod(Y,2)),A,B)' |
1890 | 1890 |
|
1891 | 1891 |
Apply boxblur algorithm to the input video. |
1892 | 1892 |
|
1893 |
-This filter accepts the parameters: |
|
1894 |
-@var{luma_radius}:@var{luma_power}:@var{chroma_radius}:@var{chroma_power}:@var{alpha_radius}:@var{alpha_power} |
|
1893 |
+The filter accepts parameters as a list of @var{key}=@var{value} |
|
1894 |
+pairs, separated by ":". If the key of the first options is omitted, |
|
1895 |
+the arguments are interpreted according to the syntax |
|
1896 |
+@option{luma_radius}:@option{luma_power}:@option{chroma_radius}:@option{chroma_power}:@option{alpha_radius}:@option{alpha_power}. |
|
1895 | 1897 |
|
1896 |
-Chroma and alpha parameters are optional, if not specified they default |
|
1897 |
-to the corresponding values set for @var{luma_radius} and |
|
1898 |
-@var{luma_power}. |
|
1898 |
+A description of the accepted options follows. |
|
1899 | 1899 |
|
1900 |
-@var{luma_radius}, @var{chroma_radius}, and @var{alpha_radius} represent |
|
1901 |
-the radius in pixels of the box used for blurring the corresponding |
|
1902 |
-input plane. They are expressions, and can contain the following |
|
1903 |
-constants: |
|
1900 |
+@table @option |
|
1901 |
+@item luma_radius, lr |
|
1902 |
+@item chroma_radius, cr |
|
1903 |
+@item alpha_radius, ar |
|
1904 |
+Set an expression for the box radius in pixels used for blurring the |
|
1905 |
+corresponding input plane. |
|
1906 |
+ |
|
1907 |
+The radius value must be a non-negative number, and must not be |
|
1908 |
+greater than the value of the expression @code{min(w,h)/2} for the |
|
1909 |
+luma and alpha planes, and of @code{min(cw,ch)/2} for the chroma |
|
1910 |
+planes. |
|
1911 |
+ |
|
1912 |
+Default value for @option{luma_radius} is "2". If not specified, |
|
1913 |
+@option{chroma_radius} and @option{alpha_radius} default to the |
|
1914 |
+corresponding value set for @option{luma_radius}. |
|
1915 |
+ |
|
1916 |
+The expressions can contain the following constants: |
|
1904 | 1917 |
@table @option |
1905 | 1918 |
@item w, h |
1906 | 1919 |
the input width and height in pixels |
... | ... |
@@ -1913,13 +1926,18 @@ horizontal and vertical chroma subsample values. For example for the |
1913 | 1913 |
pixel format "yuv422p" @var{hsub} is 2 and @var{vsub} is 1. |
1914 | 1914 |
@end table |
1915 | 1915 |
|
1916 |
-The radius must be a non-negative number, and must not be greater than |
|
1917 |
-the value of the expression @code{min(w,h)/2} for the luma and alpha planes, |
|
1918 |
-and of @code{min(cw,ch)/2} for the chroma planes. |
|
1916 |
+@item luma_power, lp |
|
1917 |
+@item chroma_power, cp |
|
1918 |
+@item alpha_power, ap |
|
1919 |
+Specify how many times the boxblur filter is applied to the |
|
1920 |
+corresponding plane. |
|
1919 | 1921 |
|
1920 |
-@var{luma_power}, @var{chroma_power}, and @var{alpha_power} represent |
|
1921 |
-how many times the boxblur filter is applied to the corresponding |
|
1922 |
-plane. |
|
1922 |
+Default value for @option{luma_power} is 2. If not specified, |
|
1923 |
+@option{chroma_power} and @option{alpha_power} default to the |
|
1924 |
+corresponding value set for @option{luma_power}. |
|
1925 |
+ |
|
1926 |
+A value of 0 will disable the effect. |
|
1927 |
+@end table |
|
1923 | 1928 |
|
1924 | 1929 |
Some examples follow: |
1925 | 1930 |
|
... | ... |
@@ -1935,7 +1953,7 @@ boxblur=2:1 |
1935 | 1935 |
@item |
1936 | 1936 |
Set luma radius to 2, alpha and chroma radius to 0 |
1937 | 1937 |
@example |
1938 |
-boxblur=2:1:0:0:0:0 |
|
1938 |
+boxblur=2:1:cr=0:ar=0 |
|
1939 | 1939 |
@end example |
1940 | 1940 |
|
1941 | 1941 |
@item |
... | ... |
@@ -30,7 +30,7 @@ |
30 | 30 |
|
31 | 31 |
#define LIBAVFILTER_VERSION_MAJOR 3 |
32 | 32 |
#define LIBAVFILTER_VERSION_MINOR 39 |
33 |
-#define LIBAVFILTER_VERSION_MICRO 100 |
|
33 |
+#define LIBAVFILTER_VERSION_MICRO 101 |
|
34 | 34 |
|
35 | 35 |
#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ |
36 | 36 |
LIBAVFILTER_VERSION_MINOR, \ |
... | ... |
@@ -28,6 +28,7 @@ |
28 | 28 |
#include "libavutil/avstring.h" |
29 | 29 |
#include "libavutil/common.h" |
30 | 30 |
#include "libavutil/eval.h" |
31 |
+#include "libavutil/opt.h" |
|
31 | 32 |
#include "libavutil/pixdesc.h" |
32 | 33 |
#include "avfilter.h" |
33 | 34 |
#include "formats.h" |
... | ... |
@@ -57,15 +58,14 @@ enum var_name { |
57 | 57 |
typedef struct { |
58 | 58 |
int radius; |
59 | 59 |
int power; |
60 |
+ char *radius_expr; |
|
60 | 61 |
} FilterParam; |
61 | 62 |
|
62 | 63 |
typedef struct { |
64 |
+ const AVClass *class; |
|
63 | 65 |
FilterParam luma_param; |
64 | 66 |
FilterParam chroma_param; |
65 | 67 |
FilterParam alpha_param; |
66 |
- char luma_radius_expr [256]; |
|
67 |
- char chroma_radius_expr[256]; |
|
68 |
- char alpha_radius_expr [256]; |
|
69 | 68 |
|
70 | 69 |
int hsub, vsub; |
71 | 70 |
int radius[4]; |
... | ... |
@@ -73,6 +73,30 @@ typedef struct { |
73 | 73 |
uint8_t *temp[2]; ///< temporary buffer used in blur_power() |
74 | 74 |
} BoxBlurContext; |
75 | 75 |
|
76 |
+#define OFFSET(x) offsetof(BoxBlurContext, x) |
|
77 |
+#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM |
|
78 |
+ |
|
79 |
+static const AVOption boxblur_options[] = { |
|
80 |
+ { "luma_radius", "set luma radius", OFFSET(luma_param.radius_expr), AV_OPT_TYPE_STRING, {.str="2"}, .flags = FLAGS }, |
|
81 |
+ { "lr", "set luma radius", OFFSET(luma_param.radius_expr), AV_OPT_TYPE_STRING, {.str="2"}, .flags = FLAGS }, |
|
82 |
+ { "luma_power", "set luma power", OFFSET(luma_param.power), AV_OPT_TYPE_INT, {.i64=2}, 0, INT_MAX, .flags = FLAGS }, |
|
83 |
+ { "lp", "set luma power", OFFSET(luma_param.power), AV_OPT_TYPE_INT, {.i64=2}, 0, INT_MAX, .flags = FLAGS }, |
|
84 |
+ |
|
85 |
+ { "chroma_radius", "set chroma radius", OFFSET(chroma_param.radius_expr), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS }, |
|
86 |
+ { "cr", "set chroma radius", OFFSET(chroma_param.radius_expr), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS }, |
|
87 |
+ { "chroma_power", "set chroma power", OFFSET(chroma_param.power), AV_OPT_TYPE_INT, {.i64=-1}, -1, INT_MAX, .flags = FLAGS }, |
|
88 |
+ { "cp", "set chroma power", OFFSET(chroma_param.power), AV_OPT_TYPE_INT, {.i64=-1}, -1, INT_MAX, .flags = FLAGS }, |
|
89 |
+ |
|
90 |
+ { "alpha_radius", "set alpha radius", OFFSET(alpha_param.radius_expr), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS }, |
|
91 |
+ { "ar", "set alpha radius", OFFSET(alpha_param.radius_expr), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS }, |
|
92 |
+ { "alpha_power", "set alpha power", OFFSET(alpha_param.power), AV_OPT_TYPE_INT, {.i64=-1}, -1, INT_MAX, .flags = FLAGS }, |
|
93 |
+ { "ap", "set alpha power", OFFSET(alpha_param.power), AV_OPT_TYPE_INT, {.i64=-1}, -1, INT_MAX, .flags = FLAGS }, |
|
94 |
+ |
|
95 |
+ { NULL } |
|
96 |
+}; |
|
97 |
+ |
|
98 |
+AVFILTER_DEFINE_CLASS(boxblur); |
|
99 |
+ |
|
76 | 100 |
#define Y 0 |
77 | 101 |
#define U 1 |
78 | 102 |
#define V 2 |
... | ... |
@@ -81,35 +105,36 @@ typedef struct { |
81 | 81 |
static av_cold int init(AVFilterContext *ctx, const char *args) |
82 | 82 |
{ |
83 | 83 |
BoxBlurContext *boxblur = ctx->priv; |
84 |
- int e; |
|
84 |
+ static const char *shorthand[] = { |
|
85 |
+ "luma_radius", "luma_power", |
|
86 |
+ "chroma_radius", "chroma_power", |
|
87 |
+ "alpha_radius", "alpha_power", |
|
88 |
+ NULL |
|
89 |
+ }; |
|
90 |
+ int ret; |
|
85 | 91 |
|
86 |
- if (!args) { |
|
87 |
- av_log(ctx, AV_LOG_ERROR, |
|
88 |
- "Filter expects 2 or 4 or 6 arguments, none provided\n"); |
|
89 |
- return AVERROR(EINVAL); |
|
90 |
- } |
|
92 |
+ boxblur->class = &boxblur_class; |
|
93 |
+ av_opt_set_defaults(boxblur); |
|
91 | 94 |
|
92 |
- e = sscanf(args, "%255[^:]:%d:%255[^:]:%d:%255[^:]:%d", |
|
93 |
- boxblur->luma_radius_expr, &boxblur->luma_param .power, |
|
94 |
- boxblur->chroma_radius_expr, &boxblur->chroma_param.power, |
|
95 |
- boxblur->alpha_radius_expr, &boxblur->alpha_param .power); |
|
95 |
+ if ((ret = av_opt_set_from_string(boxblur, args, shorthand, "=", ":")) < 0) |
|
96 |
+ return ret; |
|
96 | 97 |
|
97 |
- if (e != 2 && e != 4 && e != 6) { |
|
98 |
- av_log(ctx, AV_LOG_ERROR, |
|
99 |
- "Filter expects 2 or 4 or 6 params, provided %d\n", e); |
|
100 |
- return AVERROR(EINVAL); |
|
98 |
+ /* fill missing params */ |
|
99 |
+ if (!boxblur->chroma_param.radius_expr) { |
|
100 |
+ boxblur->chroma_param.radius_expr = av_strdup(boxblur->luma_param.radius_expr); |
|
101 |
+ if (!boxblur->chroma_param.radius_expr) |
|
102 |
+ return AVERROR(ENOMEM); |
|
101 | 103 |
} |
102 |
- |
|
103 |
- if (e < 4) { |
|
104 |
+ if (boxblur->chroma_param.power < 0) |
|
104 | 105 |
boxblur->chroma_param.power = boxblur->luma_param.power; |
105 |
- av_strlcpy(boxblur->chroma_radius_expr, boxblur->luma_radius_expr, |
|
106 |
- sizeof(boxblur->chroma_radius_expr)); |
|
106 |
+ |
|
107 |
+ if (!boxblur->alpha_param.radius_expr) { |
|
108 |
+ boxblur->alpha_param.radius_expr = av_strdup(boxblur->luma_param.radius_expr); |
|
109 |
+ if (!boxblur->alpha_param.radius_expr) |
|
110 |
+ return AVERROR(ENOMEM); |
|
107 | 111 |
} |
108 |
- if (e < 6) { |
|
112 |
+ if (boxblur->alpha_param.power < 0) |
|
109 | 113 |
boxblur->alpha_param.power = boxblur->luma_param.power; |
110 |
- av_strlcpy(boxblur->alpha_radius_expr, boxblur->luma_radius_expr, |
|
111 |
- sizeof(boxblur->alpha_radius_expr)); |
|
112 |
- } |
|
113 | 114 |
|
114 | 115 |
return 0; |
115 | 116 |
} |
... | ... |
@@ -120,6 +145,7 @@ static av_cold void uninit(AVFilterContext *ctx) |
120 | 120 |
|
121 | 121 |
av_freep(&boxblur->temp[0]); |
122 | 122 |
av_freep(&boxblur->temp[1]); |
123 |
+ av_opt_free(boxblur); |
|
123 | 124 |
} |
124 | 125 |
|
125 | 126 |
static int query_formats(AVFilterContext *ctx) |
... | ... |
@@ -163,7 +189,7 @@ static int config_input(AVFilterLink *inlink) |
163 | 163 |
var_values[VAR_VSUB] = 1<<boxblur->vsub; |
164 | 164 |
|
165 | 165 |
#define EVAL_RADIUS_EXPR(comp) \ |
166 |
- expr = boxblur->comp##_radius_expr; \ |
|
166 |
+ expr = boxblur->comp##_param.radius_expr; \ |
|
167 | 167 |
ret = av_expr_parse_and_eval(&res, expr, var_names, var_values, \ |
168 | 168 |
NULL, NULL, NULL, NULL, NULL, 0, ctx); \ |
169 | 169 |
boxblur->comp##_param.radius = res; \ |
... | ... |
@@ -366,4 +392,6 @@ AVFilter avfilter_vf_boxblur = { |
366 | 366 |
|
367 | 367 |
.inputs = avfilter_vf_boxblur_inputs, |
368 | 368 |
.outputs = avfilter_vf_boxblur_outputs, |
369 |
+ |
|
370 |
+ .priv_class = &boxblur_class, |
|
369 | 371 |
}; |