vf_scale: switch to an AVOptions-based system.

This commit is contained in:
Anton Khirnov 2013-02-25 21:21:29 +01:00
parent 5aa1a668cf
commit c334c113d4
3 changed files with 82 additions and 30 deletions

View File

@ -1645,9 +1645,21 @@ can be used to test the monowhite pixel format descriptor definition.
@section scale @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:
@table @option
@item w
Output video width.
@item h
Output video height.
@end table
The parameters @var{w} and @var{h} are expressions containing
the following constants: the following constants:
@table @option @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 the next filter, the scale filter will convert the input to the
requested format. 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. size is used for the output.
If the value for @var{width} or @var{height} is -1, the scale filter will If the value for @var{w} or @var{h} is -1, the scale filter will use, for the
use, for the respective output size, a value that maintains the aspect respective output size, a value that maintains the aspect ratio of the input
ratio of the input image. 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: 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=w=200:h=100
# scale the input to 2x # scale the input to 2x
scale=2*iw:2*ih scale=w=2*iw:h=2*ih
# the above is the same as # the above is the same as
scale=2*in_w:2*in_h scale=2*in_w:2*in_h
# scale the input to half size # 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 # increase the width, and set the height to the same size
scale=3/2*iw:ow scale=3/2*iw:ow
@ -1712,13 +1724,13 @@ scale=iw:1/PHI*iw
scale=ih*PHI:ih scale=ih*PHI:ih
# increase the height, and set the width to 3/2 of the height # 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 # 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" 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 # 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 @end example
@section select @section select

View File

@ -481,6 +481,36 @@ int avfilter_init_filter(AVFilterContext *filter, const char *args, void *opaque
int ret=0; int ret=0;
if (args && *args && filter->filter->priv_class) { 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, '=')) { if (strchr(args, '=')) {
/* assume a list of key1=value1:key2=value2:... */ /* assume a list of key1=value1:key2=value2:... */
ret = av_dict_parse_string(&options, args, "=", ":", 0); ret = av_dict_parse_string(&options, args, "=", ":", 0);

View File

@ -69,6 +69,7 @@ enum var_name {
}; };
typedef struct { typedef struct {
const AVClass *class;
struct SwsContext *sws; ///< software scaler context struct SwsContext *sws; ///< software scaler context
/** /**
@ -83,31 +84,23 @@ typedef struct {
int slice_y; ///< top of current output slice int slice_y; ///< top of current output slice
int input_is_pal; ///< set to 1 if the input format is paletted int input_is_pal; ///< set to 1 if the input format is paletted
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
char *flags_str;
} ScaleContext; } ScaleContext;
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;
av_strlcpy(scale->w_expr, "iw", sizeof(scale->w_expr)); if (scale->flags_str) {
av_strlcpy(scale->h_expr, "ih", sizeof(scale->h_expr)); 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);
scale->flags = SWS_BILINEAR; if (ret < 0)
if (args) { return ret;
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;
}
} }
return 0; return 0;
@ -292,6 +285,22 @@ static int filter_frame(AVFilterLink *link, AVFrame *in)
return ff_filter_frame(outlink, out); 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[] = { static const AVFilterPad avfilter_vf_scale_inputs[] = {
{ {
.name = "default", .name = "default",
@ -320,6 +329,7 @@ AVFilter avfilter_vf_scale = {
.query_formats = query_formats, .query_formats = query_formats,
.priv_size = sizeof(ScaleContext), .priv_size = sizeof(ScaleContext),
.priv_class = &scale_class,
.inputs = avfilter_vf_scale_inputs, .inputs = avfilter_vf_scale_inputs,
.outputs = avfilter_vf_scale_outputs, .outputs = avfilter_vf_scale_outputs,