vf_scale: switch to an AVOptions-based system.
This commit is contained in:
parent
5aa1a668cf
commit
c334c113d4
@ -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
|
||||||
|
@ -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(©);
|
||||||
|
|
||||||
|
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);
|
||||||
|
@ -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,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user