Commit 19add322 authored by Stefano Sabatini's avatar Stefano Sabatini

lavfi/scale: implement clever/insane parsing heuristic, and add a size option

If the first argument can be read as a video size, set that output size
in the scale. This allows to specify in a filtergraph scale=qcif or
scale=320x240.

This is not completely safe, for example in case of a typo in the video
size string the first argument will be read as the input width
expression, giving rise to a confusing comment.
parent d4604d10
...@@ -3017,7 +3017,9 @@ of the input, by changing the output sample aspect ratio. ...@@ -3017,7 +3017,9 @@ of the input, by changing the output sample aspect ratio.
This filter accepts a list of named options in the form of 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 @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 two options is not specified, the assumed keys for the first two
values are @code{w} and @code{h}. values are @code{w} and @code{h}. If the first option has no key and
can be interpreted like a video size specification, it will be used
to set the video size.
A description of the accepted options follows. A description of the accepted options follows.
...@@ -3050,6 +3052,10 @@ Default value is @code{0}. ...@@ -3050,6 +3052,10 @@ Default value is @code{0}.
@item flags @item flags
Set libswscale scaling flags. If not explictly specified the filter Set libswscale scaling flags. If not explictly specified the filter
applies a bilinear scaling algorithm. applies a bilinear scaling algorithm.
@item size, s
Set the video size, the value must be a valid abbreviation or in the
form @var{width}x@var{height}.
@end table @end table
The values of the @var{w} and @var{h} options are expressions The values of the @var{w} and @var{h} options are expressions
...@@ -3102,12 +3108,27 @@ Scale the input video to a size of 200x100: ...@@ -3102,12 +3108,27 @@ Scale the input video to a size of 200x100:
scale=200:100 scale=200:100
@end example @end example
@item This is equivalent to:
The above example is the same as:
@example @example
scale=w=200:h=100 scale=w=200:h=100
@end example @end example
or:
@example
scale=200x100
@end example
@item
Specify a size abbreviation for the output size:
@example
scale=qcif
@end example
which can also be written as:
@example
scale=size=qcif
@end example
@item @item
Scale the input to 2x: Scale the input to 2x:
@example @example
......
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
#define LIBAVFILTER_VERSION_MAJOR 3 #define LIBAVFILTER_VERSION_MAJOR 3
#define LIBAVFILTER_VERSION_MINOR 20 #define LIBAVFILTER_VERSION_MINOR 20
#define LIBAVFILTER_VERSION_MICRO 107 #define LIBAVFILTER_VERSION_MICRO 108
#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \
LIBAVFILTER_VERSION_MINOR, \ LIBAVFILTER_VERSION_MINOR, \
......
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
#include "libavutil/internal.h" #include "libavutil/internal.h"
#include "libavutil/mathematics.h" #include "libavutil/mathematics.h"
#include "libavutil/opt.h" #include "libavutil/opt.h"
#include "libavutil/parseutils.h"
#include "libavutil/pixdesc.h" #include "libavutil/pixdesc.h"
#include "libavutil/imgutils.h" #include "libavutil/imgutils.h"
#include "libavutil/avassert.h" #include "libavutil/avassert.h"
...@@ -78,6 +79,7 @@ typedef struct { ...@@ -78,6 +79,7 @@ typedef struct {
*/ */
int w, h; int w, h;
char *flags_str; ///sws flags string char *flags_str; ///sws flags string
char *size_str;
unsigned int flags; ///sws flags unsigned int flags; ///sws flags
int hsub, vsub; ///< chroma subsampling int hsub, vsub; ///< chroma subsampling
...@@ -94,12 +96,14 @@ typedef struct { ...@@ -94,12 +96,14 @@ typedef struct {
#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM #define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
static const AVOption scale_options[] = { static const AVOption scale_options[] = {
{ "w", "set width expression", OFFSET(w_expr), AV_OPT_TYPE_STRING, {.str = "iw"}, 0, 0, FLAGS }, { "w", "set width expression", OFFSET(w_expr), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS },
{ "width", "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 = NULL}, 0, 0, FLAGS },
{ "h", "set height expression", OFFSET(h_expr), AV_OPT_TYPE_STRING, {.str = "ih"}, 0, 0, FLAGS }, { "h", "set height expression", OFFSET(h_expr), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS },
{ "height", "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 = NULL}, 0, 0, FLAGS },
{ "flags", "set libswscale flags", OFFSET(flags_str), AV_OPT_TYPE_STRING, {.str = NULL}, 0, INT_MAX, 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 }, { "interl", "set interlacing", OFFSET(interlaced), AV_OPT_TYPE_INT, {.i64 = 0 }, -1, 1, FLAGS },
{ "size", "set video size", OFFSET(size_str), AV_OPT_TYPE_STRING, {.str = NULL}, 0, FLAGS },
{ "s", "set video size", OFFSET(size_str), AV_OPT_TYPE_STRING, {.str = NULL}, 0, FLAGS },
{ NULL }, { NULL },
}; };
...@@ -110,13 +114,45 @@ static av_cold int init(AVFilterContext *ctx, const char *args) ...@@ -110,13 +114,45 @@ static av_cold int init(AVFilterContext *ctx, const char *args)
ScaleContext *scale = ctx->priv; ScaleContext *scale = ctx->priv;
static const char *shorthand[] = { "w", "h", NULL }; static const char *shorthand[] = { "w", "h", NULL };
int ret; int ret;
const char *args0 = args;
scale->class = &scale_class; scale->class = &scale_class;
av_opt_set_defaults(scale); av_opt_set_defaults(scale);
if (args && (scale->size_str = av_get_token(&args, ":"))) {
if (av_parse_video_size(&scale->w, &scale->h, scale->size_str) < 0) {
av_freep(&scale->size_str);
args = args0;
} else if (*args)
args++;
}
if ((ret = av_opt_set_from_string(scale, args, shorthand, "=", ":")) < 0) if ((ret = av_opt_set_from_string(scale, args, shorthand, "=", ":")) < 0)
return ret; return ret;
if (scale->size_str && (scale->w_expr || scale->h_expr)) {
av_log(ctx, AV_LOG_ERROR,
"Size and width/height expressions cannot be set at the same time.\n");
return AVERROR(EINVAL);
}
if (scale->size_str) {
char buf[32];
if ((ret = av_parse_video_size(&scale->w, &scale->h, scale->size_str)) < 0) {
av_log(ctx, AV_LOG_ERROR,
"Invalid size '%s'\n", scale->size_str);
return ret;
}
snprintf(buf, sizeof(buf)-1, "%d", scale->w);
av_opt_set(scale, "w", buf, 0);
snprintf(buf, sizeof(buf)-1, "%d", scale->h);
av_opt_set(scale, "h", buf, 0);
}
if (!scale->w_expr)
av_opt_set(scale, "w", "iw", 0);
if (!scale->h_expr)
av_opt_set(scale, "h", "ih", 0);
av_log(ctx, AV_LOG_VERBOSE, "w:%s h:%s flags:%s interl:%d\n", 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->w_expr, scale->h_expr, scale->flags_str, scale->interlaced);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment