... | ... |
@@ -1645,9 +1645,21 @@ can be used to test the monowhite pixel format descriptor definition. |
1645 | 1645 |
|
1646 | 1646 |
@section scale |
1647 | 1647 |
|
1648 |
-Scale the input video to @var{width}:@var{height} and/or convert the image format. |
|
1648 |
+Scale the input video and/or convert the image format. |
|
1649 | 1649 |
|
1650 |
-The parameters @var{width} and @var{height} are expressions containing |
|
1650 |
+This filter accepts the following options: |
|
1651 |
+ |
|
1652 |
+@table @option |
|
1653 |
+ |
|
1654 |
+@item w |
|
1655 |
+Output video width. |
|
1656 |
+ |
|
1657 |
+@item h |
|
1658 |
+Output video height. |
|
1659 |
+ |
|
1660 |
+@end table |
|
1661 |
+ |
|
1662 |
+The parameters @var{w} and @var{h} are expressions containing |
|
1651 | 1663 |
the following constants: |
1652 | 1664 |
|
1653 | 1665 |
@table @option |
... | ... |
@@ -1682,27 +1694,27 @@ If the input image format is different from the format requested by |
1682 | 1682 |
the next filter, the scale filter will convert the input to the |
1683 | 1683 |
requested format. |
1684 | 1684 |
|
1685 |
-If the value for @var{width} or @var{height} is 0, the respective input |
|
1685 |
+If the value for @var{w} or @var{h} is 0, the respective input |
|
1686 | 1686 |
size is used for the output. |
1687 | 1687 |
|
1688 |
-If the value for @var{width} or @var{height} is -1, the scale filter will |
|
1689 |
-use, for the respective output size, a value that maintains the aspect |
|
1690 |
-ratio of the input image. |
|
1688 |
+If the value for @var{w} or @var{h} is -1, the scale filter will use, for the |
|
1689 |
+respective output size, a value that maintains the aspect ratio of the input |
|
1690 |
+image. |
|
1691 | 1691 |
|
1692 |
-The default value of @var{width} and @var{height} is 0. |
|
1692 |
+The default value of @var{w} and @var{h} is 0. |
|
1693 | 1693 |
|
1694 | 1694 |
Some examples follow: |
1695 | 1695 |
@example |
1696 | 1696 |
# scale the input video to a size of 200x100. |
1697 |
-scale=200:100 |
|
1697 |
+scale=w=200:h=100 |
|
1698 | 1698 |
|
1699 | 1699 |
# scale the input to 2x |
1700 |
-scale=2*iw:2*ih |
|
1700 |
+scale=w=2*iw:h=2*ih |
|
1701 | 1701 |
# the above is the same as |
1702 | 1702 |
scale=2*in_w:2*in_h |
1703 | 1703 |
|
1704 | 1704 |
# scale the input to half size |
1705 |
-scale=iw/2:ih/2 |
|
1705 |
+scale=w=iw/2:h=ih/2 |
|
1706 | 1706 |
|
1707 | 1707 |
# increase the width, and set the height to the same size |
1708 | 1708 |
scale=3/2*iw:ow |
... | ... |
@@ -1712,13 +1724,13 @@ scale=iw:1/PHI*iw |
1712 | 1712 |
scale=ih*PHI:ih |
1713 | 1713 |
|
1714 | 1714 |
# increase the height, and set the width to 3/2 of the height |
1715 |
-scale=3/2*oh:3/5*ih |
|
1715 |
+scale=w=3/2*oh:h=3/5*ih |
|
1716 | 1716 |
|
1717 | 1717 |
# increase the size, but make the size a multiple of the chroma |
1718 | 1718 |
scale="trunc(3/2*iw/hsub)*hsub:trunc(3/2*ih/vsub)*vsub" |
1719 | 1719 |
|
1720 | 1720 |
# increase the width to a maximum of 500 pixels, keep the same input aspect ratio |
1721 |
-scale='min(500\, iw*3/2):-1' |
|
1721 |
+scale=w='min(500\, iw*3/2):h=-1' |
|
1722 | 1722 |
@end example |
1723 | 1723 |
|
1724 | 1724 |
@section select |
... | ... |
@@ -481,6 +481,36 @@ int avfilter_init_filter(AVFilterContext *filter, const char *args, void *opaque |
481 | 481 |
int ret=0; |
482 | 482 |
|
483 | 483 |
if (args && *args && filter->filter->priv_class) { |
484 |
+#if FF_API_OLD_FILTER_OPTS |
|
485 |
+ if (!strcmp(filter->filter->name, "scale") && |
|
486 |
+ strchr(args, ':') < strchr(args, '=')) { |
|
487 |
+ /* old w:h:flags=<flags> syntax */ |
|
488 |
+ char *copy = av_strdup(args); |
|
489 |
+ char *p; |
|
490 |
+ |
|
491 |
+ av_log(filter, AV_LOG_WARNING, "The <w>:<h>:flags=<flags> option " |
|
492 |
+ "syntax is deprecated. Use either <w>:<h>:<flags> or " |
|
493 |
+ "w=<w>:h=<h>:flags=<flags>.\n"); |
|
494 |
+ |
|
495 |
+ if (!copy) { |
|
496 |
+ ret = AVERROR(ENOMEM); |
|
497 |
+ goto fail; |
|
498 |
+ } |
|
499 |
+ |
|
500 |
+ p = strrchr(copy, ':'); |
|
501 |
+ if (p) { |
|
502 |
+ *p++ = 0; |
|
503 |
+ ret = av_dict_parse_string(&options, p, "=", ":", 0); |
|
504 |
+ } |
|
505 |
+ if (ret >= 0) |
|
506 |
+ ret = process_unnamed_options(filter, &options, copy); |
|
507 |
+ av_freep(©); |
|
508 |
+ |
|
509 |
+ if (ret < 0) |
|
510 |
+ goto fail; |
|
511 |
+ } else |
|
512 |
+#endif |
|
513 |
+ |
|
484 | 514 |
if (strchr(args, '=')) { |
485 | 515 |
/* assume a list of key1=value1:key2=value2:... */ |
486 | 516 |
ret = av_dict_parse_string(&options, args, "=", ":", 0); |
... | ... |
@@ -69,6 +69,7 @@ enum var_name { |
69 | 69 |
}; |
70 | 70 |
|
71 | 71 |
typedef struct { |
72 |
+ const AVClass *class; |
|
72 | 73 |
struct SwsContext *sws; ///< software scaler context |
73 | 74 |
|
74 | 75 |
/** |
... | ... |
@@ -83,31 +84,23 @@ typedef struct { |
83 | 83 |
int slice_y; ///< top of current output slice |
84 | 84 |
int input_is_pal; ///< set to 1 if the input format is paletted |
85 | 85 |
|
86 |
- char w_expr[256]; ///< width expression string |
|
87 |
- char h_expr[256]; ///< height expression string |
|
86 |
+ char *w_expr; ///< width expression string |
|
87 |
+ char *h_expr; ///< height expression string |
|
88 |
+ char *flags_str; |
|
88 | 89 |
} ScaleContext; |
89 | 90 |
|
90 | 91 |
static av_cold int init(AVFilterContext *ctx, const char *args) |
91 | 92 |
{ |
92 | 93 |
ScaleContext *scale = ctx->priv; |
93 |
- const char *p; |
|
94 |
- |
|
95 |
- av_strlcpy(scale->w_expr, "iw", sizeof(scale->w_expr)); |
|
96 |
- av_strlcpy(scale->h_expr, "ih", sizeof(scale->h_expr)); |
|
97 |
- |
|
98 |
- scale->flags = SWS_BILINEAR; |
|
99 |
- if (args) { |
|
100 |
- sscanf(args, "%255[^:]:%255[^:]", scale->w_expr, scale->h_expr); |
|
101 |
- p = strstr(args,"flags="); |
|
102 |
- if (p) { |
|
103 |
- const AVClass *class = sws_get_class(); |
|
104 |
- const AVOption *o = av_opt_find(&class, "sws_flags", NULL, 0, |
|
105 |
- AV_OPT_SEARCH_FAKE_OBJ); |
|
106 |
- int ret = av_opt_eval_flags(&class, o, p + 6, &scale->flags); |
|
107 |
- |
|
108 |
- if (ret < 0) |
|
109 |
- return ret; |
|
110 |
- } |
|
94 |
+ |
|
95 |
+ if (scale->flags_str) { |
|
96 |
+ const AVClass *class = sws_get_class(); |
|
97 |
+ const AVOption *o = av_opt_find(&class, "sws_flags", NULL, 0, |
|
98 |
+ AV_OPT_SEARCH_FAKE_OBJ); |
|
99 |
+ int ret = av_opt_eval_flags(&class, o, scale->flags_str, &scale->flags); |
|
100 |
+ |
|
101 |
+ if (ret < 0) |
|
102 |
+ return ret; |
|
111 | 103 |
} |
112 | 104 |
|
113 | 105 |
return 0; |
... | ... |
@@ -292,6 +285,22 @@ static int filter_frame(AVFilterLink *link, AVFrame *in) |
292 | 292 |
return ff_filter_frame(outlink, out); |
293 | 293 |
} |
294 | 294 |
|
295 |
+#define OFFSET(x) offsetof(ScaleContext, x) |
|
296 |
+#define FLAGS AV_OPT_FLAG_VIDEO_PARAM |
|
297 |
+static const AVOption options[] = { |
|
298 |
+ { "w", "Output video width", OFFSET(w_expr), AV_OPT_TYPE_STRING, { .str = "iw" }, .flags = FLAGS }, |
|
299 |
+ { "h", "Output video height", OFFSET(h_expr), AV_OPT_TYPE_STRING, { .str = "ih" }, .flags = FLAGS }, |
|
300 |
+ { "flags", "Flags to pass to libswscale", OFFSET(flags_str), AV_OPT_TYPE_STRING, { .str = "bilinear" }, .flags = FLAGS }, |
|
301 |
+ { NULL }, |
|
302 |
+}; |
|
303 |
+ |
|
304 |
+static const AVClass scale_class = { |
|
305 |
+ .class_name = "scale", |
|
306 |
+ .item_name = av_default_item_name, |
|
307 |
+ .option = options, |
|
308 |
+ .version = LIBAVUTIL_VERSION_INT, |
|
309 |
+}; |
|
310 |
+ |
|
295 | 311 |
static const AVFilterPad avfilter_vf_scale_inputs[] = { |
296 | 312 |
{ |
297 | 313 |
.name = "default", |
... | ... |
@@ -320,6 +329,7 @@ AVFilter avfilter_vf_scale = { |
320 | 320 |
.query_formats = query_formats, |
321 | 321 |
|
322 | 322 |
.priv_size = sizeof(ScaleContext), |
323 |
+ .priv_class = &scale_class, |
|
323 | 324 |
|
324 | 325 |
.inputs = avfilter_vf_scale_inputs, |
325 | 326 |
.outputs = avfilter_vf_scale_outputs, |