History

scale: make the filter parametric

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

Stefano Sabatini committed 15 years ago

Commit 68e23c01 parent b137bf72 files · +139 −14Browse files

Unified · Split

2 files
  1. doc/filters.texi +55 −5
  2. libavfilter/vf_scale.c +84 −9
doc/filters.texi+55−5
@@ -772,13 +772,33 @@ can be used to test the monowhite pixel format descriptor definition. · 771 unmodified lines
772 772
773Scale the input video to @var{width}:@var{height} and/or convert the image format.773Scale the input video to @var{width}:@var{height} and/or convert the image format.
774 774
775For example the command:775The parameters @var{width} and @var{height} are expressions containing
776the following constants:
776 777
777@example778@table @option
778./ffmpeg -i in.avi -vf "scale=200:100" out.avi779@item E, PI, PHI
779@end example780the corresponding mathematical approximated values for e
781(euler number), pi (greek PI), phi (golden ratio)
782
783@item in_w, in_h
784the input width and heigth
785
786@item iw, ih
787same as @var{in_w} and @var{in_h}
788
789@item out_w, out_h
790the output (cropped) width and heigth
791
792@item ow, oh
793same as @var{out_w} and @var{out_h}
780 794
781will scale the input video to a size of 200x100.795@item a
796input display aspect ratio, same as @var{iw} / @var{ih}
797
798@item hsub, vsub
799horizontal and vertical chroma subsample values. For example for the
800pixel format "yuv422p" @var{hsub} is 2 and @var{vsub} is 1.
801@end table
782 802
783If the input image format is different from the format requested by803If the input image format is different from the format requested by
784the next filter, the scale filter will convert the input to the804the next filter, the scale filter will convert the input to the
@@ -793,6 +813,36 @@ ratio of the input image. · 8 unmodified lines
793 813
794The default value of @var{width} and @var{height} is 0.814The default value of @var{width} and @var{height} is 0.
795 815
816Some examples follow:
817@example
818# scale the input video to a size of 200x100.
819scale=200:100
820
821# scale the input to 2x
822scale=2*iw:2*ih
823# the above is the same as
824scale=2*in_w:2*in_h
825
826# scale the input to half size
827scale=iw/2:ih/2
828
829# increase the width, and set the height to the same size
830scale=3/2*iw:ow
831
832# seek for Greek harmony
833scale=iw:1/PHI*iw
834scale=ih*PHI:ih
835
836# increase the height, and set the width to 3/2 of the height
837scale=3/2*oh:3/5*ih
838
839# increase the size, but make the size a multiple of the chroma
840scale="trunc(3/2*iw/hsub)*hsub:trunc(3/2*ih/vsub)*vsub"
841
842# increase the width to a maximum of 500 pixels, keep the same input aspect ratio
843scale='min(500\, iw*3/2):-1'
844@end example
845
796@anchor{setdar}846@anchor{setdar}
797@section setdar847@section setdar
798 848
libavfilter/vf_scale.c+84−9
@@ -24,9 +24,39 @@ · 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 "libswscale/swscale.h"30#include "libswscale/swscale.h"
29 31
32static const char *var_names[] = {
33 "PI",
34 "PHI",
35 "E",
36 "in_w", "iw",
37 "in_h", "ih",
38 "out_w", "ow",
39 "out_h", "oh",
40 "a",
41 "hsub",
42 "vsub",
43 NULL
44};
45
46enum var_name {
47 VAR_PI,
48 VAR_PHI,
49 VAR_E,
50 VAR_IN_W, VAR_IW,
51 VAR_IN_H, VAR_IH,
52 VAR_OUT_W, VAR_OW,
53 VAR_OUT_H, VAR_OH,
54 VAR_A,
55 VAR_HSUB,
56 VAR_VSUB,
57 VARS_NB
58};
59
30typedef struct {60typedef struct {
31 struct SwsContext *sws; ///< software scaler context61 struct SwsContext *sws; ///< software scaler context
32 62
@@ -41,6 +71,9 @@ typedef struct { · 8 unmodified lines
41 int hsub, vsub; ///< chroma subsampling71 int hsub, vsub; ///< chroma subsampling
42 int slice_y; ///< top of current output slice72 int slice_y; ///< top of current output slice
43 int input_is_pal; ///< set to 1 if the input format is paletted73 int input_is_pal; ///< set to 1 if the input format is paletted
74
75 char w_expr[256]; ///< width expression string
76 char h_expr[256]; ///< height expression string
44} ScaleContext;77} ScaleContext;
45 78
46static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)79static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
@@ -48,21 +81,16 @@ static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque) · 1 unmodified line
48 ScaleContext *scale = ctx->priv;81 ScaleContext *scale = ctx->priv;
49 const char *p;82 const char *p;
50 83
84 av_strlcpy(scale->w_expr, "iw", sizeof(scale->w_expr));
85 av_strlcpy(scale->h_expr, "ih", sizeof(scale->h_expr));
86
51 scale->flags = SWS_BILINEAR;87 scale->flags = SWS_BILINEAR;
52 if (args) {88 if (args) {
53 sscanf(args, "%d:%d", &scale->w, &scale->h);89 sscanf(args, "%255[^:]:%255[^:]", scale->w_expr, scale->h_expr);
54 p = strstr(args,"flags=");90 p = strstr(args,"flags=");
55 if (p) scale->flags = strtoul(p+6, NULL, 0);91 if (p) scale->flags = strtoul(p+6, NULL, 0);
56 }92 }
57 93
58 /* sanity check params */
59 if (scale->w < -1 || scale->h < -1) {
60 av_log(ctx, AV_LOG_ERROR, "Size values less than -1 are not acceptable.\n");
61 return AVERROR(EINVAL);
62 }
63 if (scale->w == -1 && scale->h == -1)
64 scale->w = scale->h = 0;
65
66 return 0;94 return 0;
67}95}
68 96
@@ -109,6 +137,48 @@ static int config_props(AVFilterLink *outlink) · 40 unmodified lines
109 AVFilterLink *inlink = outlink->src->inputs[0];137 AVFilterLink *inlink = outlink->src->inputs[0];
110 ScaleContext *scale = ctx->priv;138 ScaleContext *scale = ctx->priv;
111 int64_t w, h;139 int64_t w, h;
140 double var_values[VARS_NB], res;
141 char *expr;
142 int ret;
143
144 var_values[VAR_PI] = M_PI;
145 var_values[VAR_PHI] = M_PHI;
146 var_values[VAR_E] = M_E;
147 var_values[VAR_IN_W] = var_values[VAR_IW] = inlink->w;
148 var_values[VAR_IN_H] = var_values[VAR_IH] = inlink->h;
149 var_values[VAR_OUT_W] = var_values[VAR_OW] = NAN;
150 var_values[VAR_OUT_H] = var_values[VAR_OH] = NAN;
151 var_values[VAR_A] = (float) inlink->w / inlink->h;
152 var_values[VAR_HSUB] = 1<<av_pix_fmt_descriptors[inlink->format].log2_chroma_w;
153 var_values[VAR_VSUB] = 1<<av_pix_fmt_descriptors[inlink->format].log2_chroma_h;
154
155 /* evaluate width and height */
156 av_expr_parse_and_eval(&res, (expr = scale->w_expr),
157 var_names, var_values,
158 NULL, NULL, NULL, NULL, NULL, 0, ctx);
159 scale->w = var_values[VAR_OUT_W] = var_values[VAR_OW] = res;
160 if ((ret = av_expr_parse_and_eval(&res, (expr = scale->h_expr),
161 var_names, var_values,
162 NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0)
163 goto fail;
164 scale->h = var_values[VAR_OUT_H] = var_values[VAR_OH] = res;
165 /* evaluate again the width, as it may depend on the output height */
166 if ((ret = av_expr_parse_and_eval(&res, (expr = scale->w_expr),
167 var_names, var_values,
168 NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0)
169 goto fail;
170 scale->w = res;
171
172 w = scale->w;
173 h = scale->h;
174
175 /* sanity check params */
176 if (w < -1 || h < -1) {
177 av_log(ctx, AV_LOG_ERROR, "Size values less than -1 are not acceptable.\n");
178 return AVERROR(EINVAL);
179 }
180 if (w == -1 && h == -1)
181 scale->w = scale->h = 0;
112 182
113 if (!(w = scale->w))183 if (!(w = scale->w))
114 w = inlink->w;184 w = inlink->w;
@@ -142,6 +212,11 @@ static int config_props(AVFilterLink *outlink) · 27 unmodified lines
142 return AVERROR(EINVAL);212 return AVERROR(EINVAL);
143 213
144 return 0;214 return 0;
215
216fail:
217 av_log(NULL, AV_LOG_ERROR,
218 "Error when evaluating the expression '%s'\n", expr);
219 return ret;
145}220}
146 221
147static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref)222static 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