[FFmpeg-cvslog] vf_scale: switch to an AVOptions-based system.

Anton Khirnov git at videolan.org
Wed Apr 10 20:43:32 CEST 2013


ffmpeg | branch: master | Anton Khirnov <anton at khirnov.net> | Mon Feb 25 21:21:29 2013 +0100| [c334c113d4d9e9a41bc38a3e4458d7ab21010401] | committer: Anton Khirnov

vf_scale: switch to an AVOptions-based system.

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=c334c113d4d9e9a41bc38a3e4458d7ab21010401
---

 doc/filters.texi       |   36 ++++++++++++++++++++++------------
 libavfilter/avfilter.c |   30 +++++++++++++++++++++++++++++
 libavfilter/vf_scale.c |   50 +++++++++++++++++++++++++++++-------------------
 3 files changed, 84 insertions(+), 32 deletions(-)

diff --git a/doc/filters.texi b/doc/filters.texi
index 8ac0f29..51f7833 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -1645,9 +1645,21 @@ can be used to test the monowhite pixel format descriptor definition.
 
 @section scale
 
-Scale the input video to @var{width}:@var{height} and/or convert the image format.
+Scale the input video and/or convert the image format.
 
-The parameters @var{width} and @var{height} are expressions containing
+This filter accepts the following options:
+
+ at table @option
+
+ at item w
+Output video width.
+
+ at item h
+Output video height.
+
+ at end table
+
+The parameters @var{w} and @var{h} are expressions containing
 the following constants:
 
 @table @option
@@ -1682,27 +1694,27 @@ If the input image format is different from the format requested by
 the next filter, the scale filter will convert the input to the
 requested format.
 
-If the value for @var{width} or @var{height} is 0, the respective input
+If the value for @var{w} or @var{h} is 0, the respective input
 size is used for the output.
 
-If the value for @var{width} or @var{height} is -1, the scale filter will
-use, for the respective output size, a value that maintains the aspect
-ratio of the input image.
+If the value for @var{w} or @var{h} is -1, the scale filter will use, for the
+respective output size, a value that maintains the aspect ratio of the input
+image.
 
-The default value of @var{width} and @var{height} is 0.
+The default value of @var{w} and @var{h} is 0.
 
 Some examples follow:
 @example
 # scale the input video to a size of 200x100.
-scale=200:100
+scale=w=200:h=100
 
 # scale the input to 2x
-scale=2*iw:2*ih
+scale=w=2*iw:h=2*ih
 # the above is the same as
 scale=2*in_w:2*in_h
 
 # scale the input to half size
-scale=iw/2:ih/2
+scale=w=iw/2:h=ih/2
 
 # increase the width, and set the height to the same size
 scale=3/2*iw:ow
@@ -1712,13 +1724,13 @@ scale=iw:1/PHI*iw
 scale=ih*PHI:ih
 
 # increase the height, and set the width to 3/2 of the height
-scale=3/2*oh:3/5*ih
+scale=w=3/2*oh:h=3/5*ih
 
 # increase the size, but make the size a multiple of the chroma
 scale="trunc(3/2*iw/hsub)*hsub:trunc(3/2*ih/vsub)*vsub"
 
 # increase the width to a maximum of 500 pixels, keep the same input aspect ratio
-scale='min(500\, iw*3/2):-1'
+scale=w='min(500\, iw*3/2):h=-1'
 @end example
 
 @section select
diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c
index 29b0583..a92c4ac 100644
--- a/libavfilter/avfilter.c
+++ b/libavfilter/avfilter.c
@@ -481,6 +481,36 @@ int avfilter_init_filter(AVFilterContext *filter, const char *args, void *opaque
     int ret=0;
 
     if (args && *args && filter->filter->priv_class) {
+#if FF_API_OLD_FILTER_OPTS
+        if (!strcmp(filter->filter->name, "scale") &&
+            strchr(args, ':') < strchr(args, '=')) {
+            /* old w:h:flags=<flags> syntax */
+            char *copy = av_strdup(args);
+            char *p;
+
+            av_log(filter, AV_LOG_WARNING, "The <w>:<h>:flags=<flags> option "
+                   "syntax is deprecated. Use either <w>:<h>:<flags> or "
+                   "w=<w>:h=<h>:flags=<flags>.\n");
+
+            if (!copy) {
+                ret = AVERROR(ENOMEM);
+                goto fail;
+            }
+
+            p = strrchr(copy, ':');
+            if (p) {
+                *p++ = 0;
+                ret = av_dict_parse_string(&options, p, "=", ":", 0);
+            }
+            if (ret >= 0)
+                ret = process_unnamed_options(filter, &options, copy);
+            av_freep(&copy);
+
+            if (ret < 0)
+                goto fail;
+        } else
+#endif
+
         if (strchr(args, '=')) {
             /* assume a list of key1=value1:key2=value2:... */
             ret = av_dict_parse_string(&options, args, "=", ":", 0);
diff --git a/libavfilter/vf_scale.c b/libavfilter/vf_scale.c
index cb2b0a3..db2762e 100644
--- a/libavfilter/vf_scale.c
+++ b/libavfilter/vf_scale.c
@@ -69,6 +69,7 @@ enum var_name {
 };
 
 typedef struct {
+    const AVClass *class;
     struct SwsContext *sws;     ///< software scaler context
 
     /**
@@ -83,31 +84,23 @@ typedef struct {
     int slice_y;                ///< top of current output slice
     int input_is_pal;           ///< set to 1 if the input format is paletted
 
-    char w_expr[256];           ///< width  expression string
-    char h_expr[256];           ///< height expression string
+    char *w_expr;               ///< width  expression string
+    char *h_expr;               ///< height expression string
+    char *flags_str;
 } ScaleContext;
 
 static av_cold int init(AVFilterContext *ctx, const char *args)
 {
     ScaleContext *scale = ctx->priv;
-    const char *p;
-
-    av_strlcpy(scale->w_expr, "iw", sizeof(scale->w_expr));
-    av_strlcpy(scale->h_expr, "ih", sizeof(scale->h_expr));
-
-    scale->flags = SWS_BILINEAR;
-    if (args) {
-        sscanf(args, "%255[^:]:%255[^:]", scale->w_expr, scale->h_expr);
-        p = strstr(args,"flags=");
-        if (p) {
-            const AVClass *class = sws_get_class();
-            const AVOption    *o = av_opt_find(&class, "sws_flags", NULL, 0,
-                                               AV_OPT_SEARCH_FAKE_OBJ);
-            int ret = av_opt_eval_flags(&class, o, p + 6, &scale->flags);
-
-            if (ret < 0)
-                return ret;
-        }
+
+    if (scale->flags_str) {
+        const AVClass *class = sws_get_class();
+        const AVOption    *o = av_opt_find(&class, "sws_flags", NULL, 0,
+                                           AV_OPT_SEARCH_FAKE_OBJ);
+        int ret = av_opt_eval_flags(&class, o, scale->flags_str, &scale->flags);
+
+        if (ret < 0)
+            return ret;
     }
 
     return 0;
@@ -292,6 +285,22 @@ static int filter_frame(AVFilterLink *link, AVFrame *in)
     return ff_filter_frame(outlink, out);
 }
 
+#define OFFSET(x) offsetof(ScaleContext, x)
+#define FLAGS AV_OPT_FLAG_VIDEO_PARAM
+static const AVOption options[] = {
+    { "w",     "Output video width",          OFFSET(w_expr),    AV_OPT_TYPE_STRING, { .str = "iw" },       .flags = FLAGS },
+    { "h",     "Output video height",         OFFSET(h_expr),    AV_OPT_TYPE_STRING, { .str = "ih" },       .flags = FLAGS },
+    { "flags", "Flags to pass to libswscale", OFFSET(flags_str), AV_OPT_TYPE_STRING, { .str = "bilinear" }, .flags = FLAGS },
+    { NULL },
+};
+
+static const AVClass scale_class = {
+    .class_name = "scale",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
 static const AVFilterPad avfilter_vf_scale_inputs[] = {
     {
         .name        = "default",
@@ -320,6 +329,7 @@ AVFilter avfilter_vf_scale = {
     .query_formats = query_formats,
 
     .priv_size = sizeof(ScaleContext),
+    .priv_class = &scale_class,
 
     .inputs    = avfilter_vf_scale_inputs,
     .outputs   = avfilter_vf_scale_outputs,



More information about the ffmpeg-cvslog mailing list