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
1004 1004
1005Scale the input video to @var{width}:@var{height} and/or convert the image format.1005Scale the input video to @var{width}:@var{height} and/or convert the image format.
1006 1006
1007For example the command:1007The parameters @var{width} and @var{height} are expressions containing
1008the following constants:
1008 1009
1009@example1010@table @option
1010./ffmpeg -i in.avi -vf "scale=200:100" out.avi1011@item E, PI, PHI
1011@end example1012the corresponding mathematical approximated values for e
1013(euler number), pi (greek PI), phi (golden ratio)
1014
1015@item in_w, in_h
1016the input width and heigth
1017
1018@item iw, ih
1019same as @var{in_w} and @var{in_h}
1012 1020
1013will scale the input video to a size of 200x100.1021@item out_w, out_h
1022the output (cropped) width and heigth
1023
1024@item ow, oh
1025same as @var{out_w} and @var{out_h}
1026
1027@item a
1028input display aspect ratio, same as @var{iw} / @var{ih}
1029
1030@item hsub, vsub
1031horizontal and vertical chroma subsample values. For example for the
1032pixel format "yuv422p" @var{hsub} is 2 and @var{vsub} is 1.
1033@end table
1014 1034
1015If the input image format is different from the format requested by1035If the input image format is different from the format requested by
1016the next filter, the scale filter will convert the input to the1036the next filter, the scale filter will convert the input to the
@@ -1025,6 +1045,36 @@ ratio of the input image. · 8 unmodified lines
1025 1045
1026The default value of @var{width} and @var{height} is 0.1046The default value of @var{width} and @var{height} is 0.
1027 1047
1048Some examples follow:
1049@example
1050# scale the input video to a size of 200x100.
1051scale=200:100
1052
1053# scale the input to 2x
1054scale=2*iw:2*ih
1055# the above is the same as
1056scale=2*in_w:2*in_h
1057
1058# scale the input to half size
1059scale=iw/2:ih/2
1060
1061# increase the width, and set the height to the same size
1062scale=3/2*iw:ow
1063
1064# seek for Greek harmony
1065scale=iw:1/PHI*iw
1066scale=ih*PHI:ih
1067
1068# increase the height, and set the width to 3/2 of the height
1069scale=3/2*oh:3/5*ih
1070
1071# increase the size, but make the size a multiple of the chroma
1072scale="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
1075scale='min(500\, iw*3/2):-1'
1076@end example
1077
1028@anchor{setdar}1078@anchor{setdar}
1029@section setdar1079@section setdar
1030 1080
libavfilter/avfilter.h+1−1
@@ -27,7 +27,7 @@ · 26 unmodified lines
27 27
28#define LIBAVFILTER_VERSION_MAJOR 128#define LIBAVFILTER_VERSION_MAJOR 1
29#define LIBAVFILTER_VERSION_MINOR 7729#define LIBAVFILTER_VERSION_MINOR 77
30#define LIBAVFILTER_VERSION_MICRO 030#define LIBAVFILTER_VERSION_MICRO 1
31 31
32#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \32#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \
33 LIBAVFILTER_VERSION_MINOR, \33 LIBAVFILTER_VERSION_MINOR, \
libavfilter/vf_scale.c+84−9
@@ -24,10 +24,40 @@ · 23 unmodified lines
24 */24 */
25 25
26#include "avfilter.h"26#include "avfilter.h"
27#include "libavutil/avstring.h"
28#include "libavutil/eval.h"
27#include "libavutil/pixdesc.h"29#include "libavutil/pixdesc.h"
28#include "libavutil/avassert.h"30#include "libavutil/avassert.h"
29#include "libswscale/swscale.h"31#include "libswscale/swscale.h"
30 32
33static 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
47enum 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
31typedef struct {61typedef struct {
32 struct SwsContext *sws; ///< software scaler context62 struct SwsContext *sws; ///< software scaler context
33 struct SwsContext *isws[2]; ///< software scaler context for interlaced material63 struct SwsContext *isws[2]; ///< software scaler context for interlaced material
@@ -44,6 +74,9 @@ typedef struct { · 10 unmodified lines
44 int slice_y; ///< top of current output slice74 int slice_y; ///< top of current output slice
45 int input_is_pal; ///< set to 1 if the input format is paletted75 int input_is_pal; ///< set to 1 if the input format is paletted
46 int interlaced;76 int interlaced;
77
78 char w_expr[256]; ///< width expression string
79 char h_expr[256]; ///< height expression string
47} ScaleContext;80} ScaleContext;
48 81
49static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)82static 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
51 ScaleContext *scale = ctx->priv;84 ScaleContext *scale = ctx->priv;
52 const char *p;85 const char *p;
53 86
87 av_strlcpy(scale->w_expr, "iw", sizeof(scale->w_expr));
88 av_strlcpy(scale->h_expr, "ih", sizeof(scale->h_expr));
89
54 scale->flags = SWS_BILINEAR;90 scale->flags = SWS_BILINEAR;
55 if (args) {91 if (args) {
56 sscanf(args, "%d:%d", &scale->w, &scale->h);92 sscanf(args, "%255[^:]:%255[^:]", scale->w_expr, scale->h_expr);
57 p = strstr(args,"flags=");93 p = strstr(args,"flags=");
58 if (p) scale->flags = strtoul(p+6, NULL, 0);94 if (p) scale->flags = strtoul(p+6, NULL, 0);
59 if(strstr(args,"interl=1")){95 if(strstr(args,"interl=1")){
@@ -62,14 +98,6 @@ static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque) · 2 unmodified lines
62 scale->interlaced=-1;98 scale->interlaced=-1;
63 }99 }
64 100
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
73 return 0;101 return 0;
74}102}
75 103
@@ -118,6 +146,48 @@ static int config_props(AVFilterLink *outlink) · 42 unmodified lines
118 AVFilterLink *inlink = outlink->src->inputs[0];146 AVFilterLink *inlink = outlink->src->inputs[0];
119 ScaleContext *scale = ctx->priv;147 ScaleContext *scale = ctx->priv;
120 int64_t w, h;148 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;
121 191
122 if (!(w = scale->w))192 if (!(w = scale->w))
123 w = inlink->w;193 w = inlink->w;
@@ -159,6 +229,11 @@ static int config_props(AVFilterLink *outlink) · 35 unmodified lines
159 return AVERROR(EINVAL);229 return AVERROR(EINVAL);
160 230
161 return 0;231 return 0;
232
233fail:
234 av_log(NULL, AV_LOG_ERROR,
235 "Error when evaluating the expression '%s'\n", expr);
236 return ret;
162}237}
163 238
164static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref)239static 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