History

scale: make the filter parametric

Make the filter accept parametric expressions for the output video size.

Stefano Sabatini committed 15 years ago

Commit d496d331 parent 25601bc3 files · +140 −15Browse files

Unified · Split

3 files
  1. doc/filters.texi +55 −5
  2. libavfilter/avfilter.h +1 −1
  3. libavfilter/vf_scale.c +84 −9
doc/filters.texi+55−5
@@ -1004,13 +1004,33 @@ can be used to test the monowhite pixel format descriptor definition. · 1003 unmodified lines
10041004
10051005 Scale the input video to @var{width}:@var{height} and/or convert the image format.
10061006
1007−For example the command:
1007+The parameters @var{width} and @var{height} are expressions containing
1008+the following constants:
10081009
1009−@example
1010−./ffmpeg -i in.avi -vf "scale=200:100" out.avi
1011−@end example
1010+@table @option
1011+@item E, PI, PHI
1012+the corresponding mathematical approximated values for e
1013+(euler number), pi (greek PI), phi (golden ratio)
1014+
1015+@item in_w, in_h
1016+the input width and heigth
1017+
1018+@item iw, ih
1019+same as @var{in_w} and @var{in_h}
10121020
1013−will scale the input video to a size of 200x100.
1021+@item out_w, out_h
1022+the output (cropped) width and heigth
1023+
1024+@item ow, oh
1025+same as @var{out_w} and @var{out_h}
1026+
1027+@item a
1028+input display aspect ratio, same as @var{iw} / @var{ih}
1029+
1030+@item hsub, vsub
1031+horizontal and vertical chroma subsample values. For example for the
1032+pixel format "yuv422p" @var{hsub} is 2 and @var{vsub} is 1.
1033+@end table
10141034
10151035 If the input image format is different from the format requested by
10161036 the next filter, the scale filter will convert the input to the
@@ -1025,6 +1045,36 @@ ratio of the input image. · 8 unmodified lines
10251045
10261046 The default value of @var{width} and @var{height} is 0.
10271047
1048+Some examples follow:
1049+@example
1050+# scale the input video to a size of 200x100.
1051+scale=200:100
1052+
1053+# scale the input to 2x
1054+scale=2*iw:2*ih
1055+# the above is the same as
1056+scale=2*in_w:2*in_h
1057+
1058+# scale the input to half size
1059+scale=iw/2:ih/2
1060+
1061+# increase the width, and set the height to the same size
1062+scale=3/2*iw:ow
1063+
1064+# seek for Greek harmony
1065+scale=iw:1/PHI*iw
1066+scale=ih*PHI:ih
1067+
1068+# increase the height, and set the width to 3/2 of the height
1069+scale=3/2*oh:3/5*ih
1070+
1071+# increase the size, but make the size a multiple of the chroma
1072+scale="trunc(3/2*iw/hsub)*hsub:trunc(3/2*ih/vsub)*vsub"
1073+
1074+# increase the width to a maximum of 500 pixels, keep the same input aspect ratio
1075+scale='min(500\, iw*3/2):-1'
1076+@end example
1077+
10281078 @anchor{setdar}
10291079 @section setdar
10301080
libavfilter/avfilter.h+1−1
@@ -27,7 +27,7 @@ · 26 unmodified lines
2727
2828 #define LIBAVFILTER_VERSION_MAJOR 1
2929 #define LIBAVFILTER_VERSION_MINOR 77
30−#define LIBAVFILTER_VERSION_MICRO 0
30+#define LIBAVFILTER_VERSION_MICRO 1
3131
3232 #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \
3333 LIBAVFILTER_VERSION_MINOR, \
libavfilter/vf_scale.c+84−9
@@ -24,10 +24,40 @@ · 23 unmodified lines
2424 */
2525
2626 #include "avfilter.h"
27+#include "libavutil/avstring.h"
28+#include "libavutil/eval.h"
2729 #include "libavutil/pixdesc.h"
2830 #include "libavutil/avassert.h"
2931 #include "libswscale/swscale.h"
3032
33+static const char *var_names[] = {
34+ "PI",
35+ "PHI",
36+ "E",
37+ "in_w", "iw",
38+ "in_h", "ih",
39+ "out_w", "ow",
40+ "out_h", "oh",
41+ "a",
42+ "hsub",
43+ "vsub",
44+ NULL
45+};
46+
47+enum var_name {
48+ VAR_PI,
49+ VAR_PHI,
50+ VAR_E,
51+ VAR_IN_W, VAR_IW,
52+ VAR_IN_H, VAR_IH,
53+ VAR_OUT_W, VAR_OW,
54+ VAR_OUT_H, VAR_OH,
55+ VAR_A,
56+ VAR_HSUB,
57+ VAR_VSUB,
58+ VARS_NB
59+};
60+
3161 typedef struct {
3262 struct SwsContext *sws; ///< software scaler context
3363 struct SwsContext *isws[2]; ///< software scaler context for interlaced material
@@ -44,6 +74,9 @@ typedef struct { · 10 unmodified lines
4474 int slice_y; ///< top of current output slice
4575 int input_is_pal; ///< set to 1 if the input format is paletted
4676 int interlaced;
77+
78+ char w_expr[256]; ///< width expression string
79+ char h_expr[256]; ///< height expression string
4780 } ScaleContext;
4881
4982 static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
@@ -51,9 +84,12 @@ static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque) · 1 unmodified line
5184 ScaleContext *scale = ctx->priv;
5285 const char *p;
5386
87+ av_strlcpy(scale->w_expr, "iw", sizeof(scale->w_expr));
88+ av_strlcpy(scale->h_expr, "ih", sizeof(scale->h_expr));
89+
5490 scale->flags = SWS_BILINEAR;
5591 if (args) {
56− sscanf(args, "%d:%d", &scale->w, &scale->h);
92+ sscanf(args, "%255[^:]:%255[^:]", scale->w_expr, scale->h_expr);
5793 p = strstr(args,"flags=");
5894 if (p) scale->flags = strtoul(p+6, NULL, 0);
5995 if(strstr(args,"interl=1")){
@@ -62,14 +98,6 @@ static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque) · 2 unmodified lines
6298 scale->interlaced=-1;
6399 }
64100
65− /* sanity check params */
66− if (scale->w < -1 || scale->h < -1) {
67− av_log(ctx, AV_LOG_ERROR, "Size values less than -1 are not acceptable.\n");
68− return AVERROR(EINVAL);
69− }
70− if (scale->w == -1 && scale->h == -1)
71− scale->w = scale->h = 0;
72−
73101 return 0;
74102 }
75103
@@ -118,6 +146,48 @@ static int config_props(AVFilterLink *outlink) · 42 unmodified lines
118146 AVFilterLink *inlink = outlink->src->inputs[0];
119147 ScaleContext *scale = ctx->priv;
120148 int64_t w, h;
149+ double var_values[VARS_NB], res;
150+ char *expr;
151+ int ret;
152+
153+ var_values[VAR_PI] = M_PI;
154+ var_values[VAR_PHI] = M_PHI;
155+ var_values[VAR_E] = M_E;
156+ var_values[VAR_IN_W] = var_values[VAR_IW] = inlink->w;
157+ var_values[VAR_IN_H] = var_values[VAR_IH] = inlink->h;
158+ var_values[VAR_OUT_W] = var_values[VAR_OW] = NAN;
159+ var_values[VAR_OUT_H] = var_values[VAR_OH] = NAN;
160+ var_values[VAR_A] = (float) inlink->w / inlink->h;
161+ var_values[VAR_HSUB] = 2<<av_pix_fmt_descriptors[inlink->format].log2_chroma_w;
162+ var_values[VAR_VSUB] = 2<<av_pix_fmt_descriptors[inlink->format].log2_chroma_h;
163+
164+ /* evaluate width and height */
165+ av_expr_parse_and_eval(&res, (expr = scale->w_expr),
166+ var_names, var_values,
167+ NULL, NULL, NULL, NULL, NULL, 0, ctx);
168+ scale->w = var_values[VAR_OW] = res;
169+ if ((ret = av_expr_parse_and_eval(&res, (expr = scale->h_expr),
170+ var_names, var_values,
171+ NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0)
172+ goto fail;
173+ scale->h = var_values[VAR_OH] = res;
174+ /* evaluate again the width, as it may depend on the output height */
175+ if ((ret = av_expr_parse_and_eval(&res, (expr = scale->w_expr),
176+ var_names, var_values,
177+ NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0)
178+ goto fail;
179+ scale->w = res;
180+
181+ w = scale->w;
182+ h = scale->h;
183+
184+ /* sanity check params */
185+ if (w < -1 || h < -1) {
186+ av_log(ctx, AV_LOG_ERROR, "Size values less than -1 are not acceptable.\n");
187+ return AVERROR(EINVAL);
188+ }
189+ if (w == -1 && h == -1)
190+ scale->w = scale->h = 0;
121191
122192 if (!(w = scale->w))
123193 w = inlink->w;
@@ -159,6 +229,11 @@ static int config_props(AVFilterLink *outlink) · 35 unmodified lines
159229 return AVERROR(EINVAL);
160230
161231 return 0;
232+
233+fail:
234+ av_log(NULL, AV_LOG_ERROR,
235+ "Error when evaluating the expression '%s'\n", expr);
236+ return ret;
162237 }
163238
164239 static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref)

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t