Browse code

lavfi/boxblur: add support to named options

Stefano Sabatini authored on 2013/02/20 23:45:02
Showing 3 changed files
... ...
@@ -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
 };