1
0
mirror of https://github.com/FFmpeg/FFmpeg.git synced 2024-11-26 19:01:44 +02:00

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

Also update documentation accordingly.
This commit is contained in:
Stefano Sabatini 2012-10-06 12:30:26 +02:00
parent 8a9b48bfa9
commit 83938c3d4c
4 changed files with 88 additions and 43 deletions

View File

@ -3009,13 +3009,51 @@ pixels will slow things down on a large logo.
@section scale @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 The scale filter forces the output display aspect ratio to be the same
of the input, by changing the output sample aspect ratio. of the input, by changing the output sample aspect ratio.
The parameters @var{width} and @var{height} are expressions containing This filter accepts a list of named options in the form of
the following constants: @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 @table @option
@item in_w, in_h @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 use, for the respective output size, a value that maintains the aspect
ratio of the input image. 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: Some examples follow:
@example @example
# scale the input video to a size of 200x100. # scale the input video to a size of 200x100.
scale=200:100 scale=200:100
# the above example is the same as:
scale=w=200:h=100
# scale the input to 2x # scale the input to 2x
scale=2*iw:2*ih scale=2*iw:2*ih
# the above is the same as # the above is the same as

View File

@ -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 106 #define LIBAVFILTER_VERSION_MICRO 107
#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, \

View File

@ -67,6 +67,7 @@ enum var_name {
}; };
typedef struct { typedef struct {
const AVClass *class;
struct SwsContext *sws; ///< software scaler context struct SwsContext *sws; ///< software scaler context
struct SwsContext *isws[2]; ///< software scaler context for interlaced material struct SwsContext *isws[2]; ///< software scaler context for interlaced material
@ -76,6 +77,7 @@ typedef struct {
* -1 = keep original aspect * -1 = keep original aspect
*/ */
int w, h; int w, h;
char *flags_str; ///sws flags string
unsigned int flags; ///sws flags unsigned int flags; ///sws flags
int hsub, vsub; ///< chroma subsampling int hsub, vsub; ///< chroma subsampling
@ -84,36 +86,49 @@ typedef struct {
int output_is_pal; ///< set to 1 if the output format is paletted int output_is_pal; ///< set to 1 if the output format is paletted
int interlaced; int interlaced;
char w_expr[256]; ///< width expression string char *w_expr; ///< width expression string
char h_expr[256]; ///< height expression string char *h_expr; ///< height expression string
} ScaleContext; } 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) static av_cold int init(AVFilterContext *ctx, const char *args)
{ {
ScaleContext *scale = ctx->priv; 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)); scale->class = &scale_class;
av_strlcpy(scale->h_expr, "ih", sizeof(scale->h_expr)); 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; scale->flags = SWS_BILINEAR;
if (args) { if (scale->flags_str) {
sscanf(args, "%255[^:]:%255[^:]", scale->w_expr, scale->h_expr);
p = strstr(args,"flags=");
if (p) {
const AVClass *class = sws_get_class(); const AVClass *class = sws_get_class();
const AVOption *o = av_opt_find(&class, "sws_flags", NULL, 0, const AVOption *o = av_opt_find(&class, "sws_flags", NULL, 0,
AV_OPT_SEARCH_FAKE_OBJ); AV_OPT_SEARCH_FAKE_OBJ);
int ret = av_opt_eval_flags(&class, o, p + 6, &scale->flags); int ret = av_opt_eval_flags(&class, o, scale->flags_str, &scale->flags);
if (ret < 0) if (ret < 0)
return ret; return ret;
} }
if(strstr(args,"interl=1")){
scale->interlaced=1;
}else if(strstr(args,"interl=-1"))
scale->interlaced=-1;
}
return 0; return 0;
} }
@ -125,6 +140,7 @@ static av_cold void uninit(AVFilterContext *ctx)
sws_freeContext(scale->isws[0]); sws_freeContext(scale->isws[0]);
sws_freeContext(scale->isws[1]); sws_freeContext(scale->isws[1]);
scale->sws = NULL; scale->sws = NULL;
av_opt_free(scale);
} }
static int query_formats(AVFilterContext *ctx) static int query_formats(AVFilterContext *ctx)
@ -283,14 +299,17 @@ static int start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
AVFilterLink *outlink = link->dst->outputs[0]; AVFilterLink *outlink = link->dst->outputs[0];
AVFilterBufferRef *outpicref, *for_next_filter; AVFilterBufferRef *outpicref, *for_next_filter;
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(link->format); const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(link->format);
char buf[32];
int ret = 0; int ret = 0;
if( picref->video->w != link->w if( picref->video->w != link->w
|| picref->video->h != link->h || picref->video->h != link->h
|| picref->format != link->format) { || picref->format != link->format) {
int ret; int ret;
snprintf(scale->w_expr, sizeof(scale->w_expr)-1, "%d", outlink->w); snprintf(buf, sizeof(buf)-1, "%d", outlink->w);
snprintf(scale->h_expr, sizeof(scale->h_expr)-1, "%d", outlink->h); 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]->format = picref->format;
link->dst->inputs[0]->w = picref->video->w; link->dst->inputs[0]->w = picref->video->w;

View File

@ -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 "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 "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 # TODO: add tests for
# direct rendering, # direct rendering,