Browse code

lavfi/scale: accept named options, make parsing more robust

Also update documentation accordingly.

Stefano Sabatini authored on 2012/10/06 19:30:26
Showing 4 changed files
... ...
@@ -3009,13 +3009,51 @@ pixels will slow things down on a large logo.
3009 3009
 
3010 3010
 @section scale
3011 3011
 
3012
-Scale (resize) the input video to @var{width}:@var{height}[:@var{interl}=@{1|-1@}] and/or convert the image format.
3012
+Scale (resize) the input video, using the libswscale library.
3013 3013
 
3014 3014
 The scale filter forces the output display aspect ratio to be the same
3015 3015
 of the input, by changing the output sample aspect ratio.
3016 3016
 
3017
-The parameters @var{width} and @var{height} are expressions containing
3018
-the following constants:
3017
+This filter accepts a list of named options in the form of
3018
+@var{key}=@var{value} pairs separated by ":". If the key for the first
3019
+two options is not specified, the assumed keys for the first two
3020
+values are @code{w} and @code{h}.
3021
+
3022
+A description of the accepted options follows.
3023
+
3024
+@table @option
3025
+@item width, w
3026
+Set the video width expression, default value is @code{iw}. See below
3027
+for the list of accepted constants.
3028
+
3029
+@item height, h
3030
+Set the video heiht expression, default value is @code{ih}.
3031
+See below for the list of accepted constants.
3032
+
3033
+@item interl
3034
+Set the interlacing. It accepts the following values:
3035
+
3036
+@table @option
3037
+@item 1
3038
+force interlaced aware scaling
3039
+
3040
+@item 0
3041
+do not apply interlaced scaling
3042
+
3043
+@item -1
3044
+select interlaced aware scaling depending on whether the source frames
3045
+are flagged as interlaced or not
3046
+@end table
3047
+
3048
+Default value is @code{0}.
3049
+
3050
+@item flags
3051
+Set libswscale scaling flags. If not explictly specified the filter
3052
+applies a bilinear scaling algorithm.
3053
+@end table
3054
+
3055
+The values of the @var{w} and @var{h} options are expressions
3056
+containing the following constants:
3019 3057
 
3020 3058
 @table @option
3021 3059
 @item in_w, in_h
... ...
@@ -3055,26 +3093,14 @@ If the value for @var{width} or @var{height} is -1, the scale filter will
3055 3055
 use, for the respective output size, a value that maintains the aspect
3056 3056
 ratio of the input image.
3057 3057
 
3058
-The default value of @var{width} and @var{height} is 0.
3059
-
3060
-Valid values for the optional parameter @var{interl} are:
3061
-
3062
-@table @option
3063
-@item 1
3064
-force interlaced aware scaling
3065
-
3066
-@item -1
3067
-select interlaced aware scaling depending on whether the source frames
3068
-are flagged as interlaced or not
3069
-@end table
3070
-
3071
-Unless @var{interl} is set to one of the above options, interlaced scaling will not be used.
3072
-
3073 3058
 Some examples follow:
3074 3059
 @example
3075 3060
 # scale the input video to a size of 200x100.
3076 3061
 scale=200:100
3077 3062
 
3063
+# the above example is the same as:
3064
+scale=w=200:h=100
3065
+
3078 3066
 # scale the input to 2x
3079 3067
 scale=2*iw:2*ih
3080 3068
 # the above is the same as
... ...
@@ -30,7 +30,7 @@
30 30
 
31 31
 #define LIBAVFILTER_VERSION_MAJOR  3
32 32
 #define LIBAVFILTER_VERSION_MINOR  20
33
-#define LIBAVFILTER_VERSION_MICRO 106
33
+#define LIBAVFILTER_VERSION_MICRO 107
34 34
 
35 35
 #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \
36 36
                                                LIBAVFILTER_VERSION_MINOR, \
... ...
@@ -67,6 +67,7 @@ enum var_name {
67 67
 };
68 68
 
69 69
 typedef struct {
70
+    const AVClass *class;
70 71
     struct SwsContext *sws;     ///< software scaler context
71 72
     struct SwsContext *isws[2]; ///< software scaler context for interlaced material
72 73
 
... ...
@@ -76,6 +77,7 @@ typedef struct {
76 76
      *  -1 = keep original aspect
77 77
      */
78 78
     int w, h;
79
+    char *flags_str;            ///sws flags string
79 80
     unsigned int flags;         ///sws flags
80 81
 
81 82
     int hsub, vsub;             ///< chroma subsampling
... ...
@@ -84,35 +86,48 @@ typedef struct {
84 84
     int output_is_pal;          ///< set to 1 if the output format is paletted
85 85
     int interlaced;
86 86
 
87
-    char w_expr[256];           ///< width  expression string
88
-    char h_expr[256];           ///< height expression string
87
+    char *w_expr;               ///< width  expression string
88
+    char *h_expr;               ///< height expression string
89 89
 } ScaleContext;
90 90
 
91
+#define OFFSET(x) offsetof(ScaleContext, x)
92
+#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
93
+
94
+static const AVOption scale_options[] = {
95
+    { "w",      "set width expression",    OFFSET(w_expr), AV_OPT_TYPE_STRING, {.str = "iw"}, 0, 0, FLAGS },
96
+    { "width",  "set width expression",    OFFSET(w_expr), AV_OPT_TYPE_STRING, {.str = "iw"}, 0, 0, FLAGS },
97
+    { "h",      "set height expression",   OFFSET(h_expr), AV_OPT_TYPE_STRING, {.str = "ih"}, 0, 0, FLAGS },
98
+    { "height", "set height expression",   OFFSET(h_expr), AV_OPT_TYPE_STRING, {.str = "ih"}, 0, 0, FLAGS },
99
+    { "flags",  "set libswscale flags",    OFFSET(flags_str), AV_OPT_TYPE_STRING, {.str = NULL}, 0, INT_MAX, FLAGS },
100
+    { "interl", "set interlacing", OFFSET(interlaced), AV_OPT_TYPE_INT, {.i64 = 0 }, -1, 1, FLAGS },
101
+    { NULL },
102
+};
103
+
104
+AVFILTER_DEFINE_CLASS(scale);
105
+
91 106
 static av_cold int init(AVFilterContext *ctx, const char *args)
92 107
 {
93 108
     ScaleContext *scale = ctx->priv;
94
-    const char *p;
109
+    static const char *shorthand[] = { "w", "h", NULL };
110
+    int ret;
95 111
 
96
-    av_strlcpy(scale->w_expr, "iw", sizeof(scale->w_expr));
97
-    av_strlcpy(scale->h_expr, "ih", sizeof(scale->h_expr));
112
+    scale->class = &scale_class;
113
+    av_opt_set_defaults(scale);
114
+
115
+    if ((ret = av_opt_set_from_string(scale, args, shorthand, "=", ":")) < 0)
116
+        return ret;
117
+
118
+    av_log(ctx, AV_LOG_VERBOSE, "w:%s h:%s flags:%s interl:%d\n",
119
+           scale->w_expr, scale->h_expr, scale->flags_str, scale->interlaced);
98 120
 
99 121
     scale->flags = SWS_BILINEAR;
100
-    if (args) {
101
-        sscanf(args, "%255[^:]:%255[^:]", scale->w_expr, scale->h_expr);
102
-        p = strstr(args,"flags=");
103
-        if (p) {
104
-            const AVClass *class = sws_get_class();
105
-            const AVOption    *o = av_opt_find(&class, "sws_flags", NULL, 0,
106
-                                               AV_OPT_SEARCH_FAKE_OBJ);
107
-            int ret = av_opt_eval_flags(&class, o, p + 6, &scale->flags);
108
-
109
-            if (ret < 0)
110
-                return ret;
111
-        }
112
-        if(strstr(args,"interl=1")){
113
-            scale->interlaced=1;
114
-        }else if(strstr(args,"interl=-1"))
115
-            scale->interlaced=-1;
122
+    if (scale->flags_str) {
123
+        const AVClass *class = sws_get_class();
124
+        const AVOption    *o = av_opt_find(&class, "sws_flags", NULL, 0,
125
+                                           AV_OPT_SEARCH_FAKE_OBJ);
126
+        int ret = av_opt_eval_flags(&class, o, scale->flags_str, &scale->flags);
127
+        if (ret < 0)
128
+            return ret;
116 129
     }
117 130
 
118 131
     return 0;
... ...
@@ -125,6 +140,7 @@ static av_cold void uninit(AVFilterContext *ctx)
125 125
     sws_freeContext(scale->isws[0]);
126 126
     sws_freeContext(scale->isws[1]);
127 127
     scale->sws = NULL;
128
+    av_opt_free(scale);
128 129
 }
129 130
 
130 131
 static int query_formats(AVFilterContext *ctx)
... ...
@@ -283,14 +299,17 @@ static int start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
283 283
     AVFilterLink *outlink = link->dst->outputs[0];
284 284
     AVFilterBufferRef *outpicref, *for_next_filter;
285 285
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(link->format);
286
+    char buf[32];
286 287
     int ret = 0;
287 288
 
288 289
     if(   picref->video->w != link->w
289 290
        || picref->video->h != link->h
290 291
        || picref->format   != link->format) {
291 292
         int ret;
292
-        snprintf(scale->w_expr, sizeof(scale->w_expr)-1, "%d", outlink->w);
293
-        snprintf(scale->h_expr, sizeof(scale->h_expr)-1, "%d", outlink->h);
293
+        snprintf(buf, sizeof(buf)-1, "%d", outlink->w);
294
+        av_opt_set(scale, "w", buf, 0);
295
+        snprintf(buf, sizeof(buf)-1, "%d", outlink->h);
296
+        av_opt_set(scale, "h", buf, 0);
294 297
 
295 298
         link->dst->inputs[0]->format = picref->format;
296 299
         link->dst->inputs[0]->w      = picref->video->w;
... ...
@@ -132,7 +132,7 @@ do_lavfi_lavd() {
132 132
 
133 133
 do_lavfi_lavd "life"                 "life=s=40x40:r=5:seed=42:mold=64" -t 2
134 134
 do_lavfi_lavd "testsrc"              "testsrc=r=7:n=2:d=10"
135
-do_lavfi_lavd "scalenorm"            "sws_flags=+accurate_rnd+bitexact;testsrc=s=128x96:d=1:r=5,format=yuv420p[a];testsrc=s=160x120:d=1:r=5[b];[a][b]concat=unsafe=1,scale=::flags=+accurate_rnd+bitexact"
135
+do_lavfi_lavd "scalenorm"            "sws_flags=+accurate_rnd+bitexact;testsrc=s=128x96:d=1:r=5,format=yuv420p[a];testsrc=s=160x120:d=1:r=5[b];[a][b]concat=unsafe=1,scale=flags=+accurate_rnd+bitexact"
136 136
 
137 137
 # TODO: add tests for
138 138
 # direct rendering,