[FFmpeg-devel] [PATCH] lavfi/scale: accept named option, make parsing more robust
Stefano Sabatini
stefasab at gmail.com
Sat Oct 6 12:39:40 CEST 2012
Also update documentation accordingly.
TODO: bump micro
---
doc/filters.texi | 61 +++++++++++++++++++++++++++++++-------------
libavfilter/vf_scale.c | 66 +++++++++++++++++++++++++++++------------------
2 files changed, 84 insertions(+), 43 deletions(-)
diff --git a/doc/filters.texi b/doc/filters.texi
index 69a8ee1..d56a51a 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -3005,13 +3005,50 @@ pixels will slow things down on a large logo.
@section scale
-Scale the input video to @var{width}:@var{height}[:@var{interl}=@{1|-1@}] and/or convert the image format.
+Scale the input video.
The scale filter forces the output display aspect ratio to be the same
of the input, by changing the output sample aspect ratio.
-The parameters @var{width} and @var{height} are expressions containing
-the following constants:
+This filter accepts a list of named options in the form of
+ at var{key}=@var{value} pairs separated by ":". If the key for the first
+two options is not specified, the assumed keys for the first two
+values are @code{w} and @code{h}.
+
+A description of the accepted options follows.
+
+ at table @option
+ at item width, w
+Set the video width expression, default value is @code{iw}. See below
+for the list of accepted constants.
+
+ at item height, h
+Set the video heiht expression, default value is @code{ih}.
+See below for the list of accepted constants.
+
+ at item interl
+Set the interlacing. It accepts the following values:
+
+ at table @option
+ at item 1
+force interlaced aware scaling
+
+ at item 0
+do not apply interlaced scaling
+
+ at item -1
+select interlaced aware scaling depending on whether the source frames
+are flagged as interlaced or not
+ at end table
+
+Default value is @code{0}.
+
+ at item flags
+Set libswscale scaling flags.
+ at end table
+
+The values of the @var{w} and @var{h} options are expressions
+containing the following constants:
@table @option
@item in_w, in_h
@@ -3051,26 +3088,14 @@ 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.
-The default value of @var{width} and @var{height} is 0.
-
-Valid values for the optional parameter @var{interl} are:
-
- at table @option
- at item 1
-force interlaced aware scaling
-
- at item -1
-select interlaced aware scaling depending on whether the source frames
-are flagged as interlaced or not
- at end table
-
-Unless @var{interl} is set to one of the above options, interlaced scaling will not be used.
-
Some examples follow:
@example
# scale the input video to a size of 200x100.
scale=200:100
+# the above example is the same as:
+scale=w=200:h=100
+
# scale the input to 2x
scale=2*iw:2*ih
# the above is the same as
diff --git a/libavfilter/vf_scale.c b/libavfilter/vf_scale.c
index 49988bf..b7c5272 100644
--- a/libavfilter/vf_scale.c
+++ b/libavfilter/vf_scale.c
@@ -67,6 +67,7 @@ enum var_name {
};
typedef struct {
+ const AVClass *class;
struct SwsContext *sws; ///< software scaler context
struct SwsContext *isws[2]; ///< software scaler context for interlaced material
@@ -76,7 +77,8 @@ typedef struct {
* -1 = keep original aspect
*/
int w, h;
- unsigned int flags; ///sws flags
+ const char *flags_str; ///sws flags string
+ int flags; ///sws flags
int hsub, vsub; ///< chroma subsampling
int slice_y; ///< top of current output slice
@@ -84,35 +86,47 @@ typedef struct {
int output_is_pal; ///< set to 1 if the output format is paletted
int interlaced;
- 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
} ScaleContext;
+#define OFFSET(x) offsetof(ScaleContext, x)
+#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
+
+static const AVOption scale_options[] = {
+ { "w", "set width expression", OFFSET(w_expr), AV_OPT_TYPE_STRING, {.str = "iw"}, 0, 0, FLAGS },
+ { "width", "set width expression", OFFSET(w_expr), AV_OPT_TYPE_STRING, {.str = "iw"}, 0, 0, FLAGS },
+ { "h", "set height expression", OFFSET(h_expr), AV_OPT_TYPE_STRING, {.str = "ih"}, 0, 0, FLAGS },
+ { "height", "set height expression", OFFSET(h_expr), AV_OPT_TYPE_STRING, {.str = "ih"}, 0, 0, FLAGS },
+ { "flags", "set libswscale flags", OFFSET(flags_str), AV_OPT_TYPE_STRING, {.str = "bilinear"}, 0, INT_MAX, FLAGS },
+ { "interl", "set interlacing", OFFSET(interlaced), AV_OPT_TYPE_INT, {.i64 = 0 }, -1, 1, FLAGS },
+ { NULL },
+};
+
+AVFILTER_DEFINE_CLASS(scale);
+
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(strstr(args,"interl=1")){
- scale->interlaced=1;
- }else if(strstr(args,"interl=-1"))
- scale->interlaced=-1;
+ const char *shorthand[] = { "w", "h" };
+ int ret;
+
+ scale->class = &scale_class;
+ av_opt_set_defaults(scale);
+
+ if ((ret = av_opt_set_from_string(scale, args, shorthand, "=", ":")) < 0)
+ return ret;
+
+ av_log(ctx, AV_LOG_VERBOSE, "w:%s h:%s flags:%s interl:%d\n",
+ scale->w_expr, scale->h_expr, scale->flags_str, scale->interlaced);
+
+ 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;
@@ -124,6 +138,7 @@ static av_cold void uninit(AVFilterContext *ctx)
sws_freeContext(scale->sws);
sws_freeContext(scale->isws[0]);
sws_freeContext(scale->isws[1]);
+ av_opt_free(scale);
scale->sws = NULL;
}
@@ -416,4 +431,5 @@ AVFilter avfilter_vf_scale = {
.type = AVMEDIA_TYPE_VIDEO,
.config_props = config_props, },
{ .name = NULL}},
+ .priv_class = &scale_class,
};
--
1.7.5.4
More information about the ffmpeg-devel
mailing list