summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/filters.texi62
-rw-r--r--libavfilter/version.h2
-rw-r--r--libavfilter/vf_scale.c65
-rwxr-xr-xtests/lavfi-regression.sh2
4 files changed, 88 insertions, 43 deletions
diff --git a/doc/filters.texi b/doc/filters.texi
index 19b8bf2229..94ce59481b 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -3009,13 +3009,51 @@ pixels will slow things down on a large logo.
@section scale
-Scale (resize) the input video to @var{width}:@var{height}[:@var{interl}=@{1|-1@}] and/or convert the image format.
+Scale (resize) the input video, using the libswscale library.
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
+@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.
+
+@table @option
+@item width, w
+Set the video width expression, default value is @code{iw}. See below
+for the list of accepted constants.
+
+@item height, h
+Set the video heiht expression, default value is @code{ih}.
+See below for the list of accepted constants.
+
+@item interl
+Set the interlacing. It accepts the following values:
+
+@table @option
+@item 1
+force interlaced aware scaling
+
+@item 0
+do not apply interlaced scaling
+
+@item -1
+select interlaced aware scaling depending on whether the source frames
+are flagged as interlaced or not
+@end table
+
+Default value is @code{0}.
+
+@item flags
+Set libswscale scaling flags. If not explictly specified the filter
+applies a bilinear scaling algorithm.
+@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
@@ -3055,26 +3093,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:
-
-@table @option
-@item 1
-force interlaced aware scaling
-
-@item -1
-select interlaced aware scaling depending on whether the source frames
-are flagged as interlaced or not
-@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/version.h b/libavfilter/version.h
index 7b559031be..3ce13c14dd 100644
--- a/libavfilter/version.h
+++ b/libavfilter/version.h
@@ -30,7 +30,7 @@
#define LIBAVFILTER_VERSION_MAJOR 3
#define LIBAVFILTER_VERSION_MINOR 20
-#define LIBAVFILTER_VERSION_MICRO 106
+#define LIBAVFILTER_VERSION_MICRO 107
#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \
LIBAVFILTER_VERSION_MINOR, \
diff --git a/libavfilter/vf_scale.c b/libavfilter/vf_scale.c
index c42f9f20aa..1a4784dde5 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,6 +77,7 @@ typedef struct {
* -1 = keep original aspect
*/
int w, h;
+ char *flags_str; ///sws flags string
unsigned int flags; ///sws flags
int hsub, vsub; ///< chroma subsampling
@@ -84,35 +86,48 @@ 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 = NULL}, 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;
+ static const char *shorthand[] = { "w", "h", NULL };
+ int ret;
- av_strlcpy(scale->w_expr, "iw", sizeof(scale->w_expr));
- av_strlcpy(scale->h_expr, "ih", sizeof(scale->h_expr));
+ 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);
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;
+ 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;
@@ -125,6 +140,7 @@ static av_cold void uninit(AVFilterContext *ctx)
sws_freeContext(scale->isws[0]);
sws_freeContext(scale->isws[1]);
scale->sws = NULL;
+ av_opt_free(scale);
}
static int query_formats(AVFilterContext *ctx)
@@ -283,14 +299,17 @@ static int start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
AVFilterLink *outlink = link->dst->outputs[0];
AVFilterBufferRef *outpicref, *for_next_filter;
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(link->format);
+ char buf[32];
int ret = 0;
if( picref->video->w != link->w
|| picref->video->h != link->h
|| picref->format != link->format) {
int ret;
- snprintf(scale->w_expr, sizeof(scale->w_expr)-1, "%d", outlink->w);
- snprintf(scale->h_expr, sizeof(scale->h_expr)-1, "%d", outlink->h);
+ snprintf(buf, sizeof(buf)-1, "%d", outlink->w);
+ av_opt_set(scale, "w", buf, 0);
+ snprintf(buf, sizeof(buf)-1, "%d", outlink->h);
+ av_opt_set(scale, "h", buf, 0);
link->dst->inputs[0]->format = picref->format;
link->dst->inputs[0]->w = picref->video->w;
diff --git a/tests/lavfi-regression.sh b/tests/lavfi-regression.sh
index 5027f9deb7..703d56c1b1 100755
--- a/tests/lavfi-regression.sh
+++ b/tests/lavfi-regression.sh
@@ -132,7 +132,7 @@ do_lavfi_lavd() {
do_lavfi_lavd "life" "life=s=40x40:r=5:seed=42:mold=64" -t 2
do_lavfi_lavd "testsrc" "testsrc=r=7:n=2:d=10"
-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"
+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"
# TODO: add tests for
# direct rendering,