Also update documentation accordingly.
Stefano Sabatini authored on 2012/10/06 19:30:26... | ... |
@@ -3009,13 +3009,51 @@ pixels will slow things down on a large logo. |
3009 | 3009 |
|
3010 | 3010 |
@section scale |
3011 | 3011 |
|
3012 |
-Scale (resize) the input video to @var{width}:@var{height}[:@var{interl}=@{1|-1@}] and/or convert the image format. |
|
3012 |
+Scale (resize) the input video, using the libswscale library. |
|
3013 | 3013 |
|
3014 | 3014 |
The scale filter forces the output display aspect ratio to be the same |
3015 | 3015 |
of the input, by changing the output sample aspect ratio. |
3016 | 3016 |
|
3017 |
-The parameters @var{width} and @var{height} are expressions containing |
|
3018 |
-the following constants: |
|
3017 |
+This filter accepts a list of named options in the form of |
|
3018 |
+@var{key}=@var{value} pairs separated by ":". If the key for the first |
|
3019 |
+two options is not specified, the assumed keys for the first two |
|
3020 |
+values are @code{w} and @code{h}. |
|
3021 |
+ |
|
3022 |
+A description of the accepted options follows. |
|
3023 |
+ |
|
3024 |
+@table @option |
|
3025 |
+@item width, w |
|
3026 |
+Set the video width expression, default value is @code{iw}. See below |
|
3027 |
+for the list of accepted constants. |
|
3028 |
+ |
|
3029 |
+@item height, h |
|
3030 |
+Set the video heiht expression, default value is @code{ih}. |
|
3031 |
+See below for the list of accepted constants. |
|
3032 |
+ |
|
3033 |
+@item interl |
|
3034 |
+Set the interlacing. It accepts the following values: |
|
3035 |
+ |
|
3036 |
+@table @option |
|
3037 |
+@item 1 |
|
3038 |
+force interlaced aware scaling |
|
3039 |
+ |
|
3040 |
+@item 0 |
|
3041 |
+do not apply interlaced scaling |
|
3042 |
+ |
|
3043 |
+@item -1 |
|
3044 |
+select interlaced aware scaling depending on whether the source frames |
|
3045 |
+are flagged as interlaced or not |
|
3046 |
+@end table |
|
3047 |
+ |
|
3048 |
+Default value is @code{0}. |
|
3049 |
+ |
|
3050 |
+@item flags |
|
3051 |
+Set libswscale scaling flags. If not explictly specified the filter |
|
3052 |
+applies a bilinear scaling algorithm. |
|
3053 |
+@end table |
|
3054 |
+ |
|
3055 |
+The values of the @var{w} and @var{h} options are expressions |
|
3056 |
+containing the following constants: |
|
3019 | 3057 |
|
3020 | 3058 |
@table @option |
3021 | 3059 |
@item in_w, in_h |
... | ... |
@@ -3055,26 +3093,14 @@ If the value for @var{width} or @var{height} is -1, the scale filter will |
3055 | 3055 |
use, for the respective output size, a value that maintains the aspect |
3056 | 3056 |
ratio of the input image. |
3057 | 3057 |
|
3058 |
-The default value of @var{width} and @var{height} is 0. |
|
3059 |
- |
|
3060 |
-Valid values for the optional parameter @var{interl} are: |
|
3061 |
- |
|
3062 |
-@table @option |
|
3063 |
-@item 1 |
|
3064 |
-force interlaced aware scaling |
|
3065 |
- |
|
3066 |
-@item -1 |
|
3067 |
-select interlaced aware scaling depending on whether the source frames |
|
3068 |
-are flagged as interlaced or not |
|
3069 |
-@end table |
|
3070 |
- |
|
3071 |
-Unless @var{interl} is set to one of the above options, interlaced scaling will not be used. |
|
3072 |
- |
|
3073 | 3058 |
Some examples follow: |
3074 | 3059 |
@example |
3075 | 3060 |
# scale the input video to a size of 200x100. |
3076 | 3061 |
scale=200:100 |
3077 | 3062 |
|
3063 |
+# the above example is the same as: |
|
3064 |
+scale=w=200:h=100 |
|
3065 |
+ |
|
3078 | 3066 |
# scale the input to 2x |
3079 | 3067 |
scale=2*iw:2*ih |
3080 | 3068 |
# the above is the same as |
... | ... |
@@ -30,7 +30,7 @@ |
30 | 30 |
|
31 | 31 |
#define LIBAVFILTER_VERSION_MAJOR 3 |
32 | 32 |
#define LIBAVFILTER_VERSION_MINOR 20 |
33 |
-#define LIBAVFILTER_VERSION_MICRO 106 |
|
33 |
+#define LIBAVFILTER_VERSION_MICRO 107 |
|
34 | 34 |
|
35 | 35 |
#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ |
36 | 36 |
LIBAVFILTER_VERSION_MINOR, \ |
... | ... |
@@ -67,6 +67,7 @@ enum var_name { |
67 | 67 |
}; |
68 | 68 |
|
69 | 69 |
typedef struct { |
70 |
+ const AVClass *class; |
|
70 | 71 |
struct SwsContext *sws; ///< software scaler context |
71 | 72 |
struct SwsContext *isws[2]; ///< software scaler context for interlaced material |
72 | 73 |
|
... | ... |
@@ -76,6 +77,7 @@ typedef struct { |
76 | 76 |
* -1 = keep original aspect |
77 | 77 |
*/ |
78 | 78 |
int w, h; |
79 |
+ char *flags_str; ///sws flags string |
|
79 | 80 |
unsigned int flags; ///sws flags |
80 | 81 |
|
81 | 82 |
int hsub, vsub; ///< chroma subsampling |
... | ... |
@@ -84,35 +86,48 @@ typedef struct { |
84 | 84 |
int output_is_pal; ///< set to 1 if the output format is paletted |
85 | 85 |
int interlaced; |
86 | 86 |
|
87 |
- char w_expr[256]; ///< width expression string |
|
88 |
- char h_expr[256]; ///< height expression string |
|
87 |
+ char *w_expr; ///< width expression string |
|
88 |
+ char *h_expr; ///< height expression string |
|
89 | 89 |
} ScaleContext; |
90 | 90 |
|
91 |
+#define OFFSET(x) offsetof(ScaleContext, x) |
|
92 |
+#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM |
|
93 |
+ |
|
94 |
+static const AVOption scale_options[] = { |
|
95 |
+ { "w", "set width expression", OFFSET(w_expr), AV_OPT_TYPE_STRING, {.str = "iw"}, 0, 0, FLAGS }, |
|
96 |
+ { "width", "set width expression", OFFSET(w_expr), AV_OPT_TYPE_STRING, {.str = "iw"}, 0, 0, FLAGS }, |
|
97 |
+ { "h", "set height expression", OFFSET(h_expr), AV_OPT_TYPE_STRING, {.str = "ih"}, 0, 0, FLAGS }, |
|
98 |
+ { "height", "set height expression", OFFSET(h_expr), AV_OPT_TYPE_STRING, {.str = "ih"}, 0, 0, FLAGS }, |
|
99 |
+ { "flags", "set libswscale flags", OFFSET(flags_str), AV_OPT_TYPE_STRING, {.str = NULL}, 0, INT_MAX, FLAGS }, |
|
100 |
+ { "interl", "set interlacing", OFFSET(interlaced), AV_OPT_TYPE_INT, {.i64 = 0 }, -1, 1, FLAGS }, |
|
101 |
+ { NULL }, |
|
102 |
+}; |
|
103 |
+ |
|
104 |
+AVFILTER_DEFINE_CLASS(scale); |
|
105 |
+ |
|
91 | 106 |
static av_cold int init(AVFilterContext *ctx, const char *args) |
92 | 107 |
{ |
93 | 108 |
ScaleContext *scale = ctx->priv; |
94 |
- const char *p; |
|
109 |
+ static const char *shorthand[] = { "w", "h", NULL }; |
|
110 |
+ int ret; |
|
95 | 111 |
|
96 |
- av_strlcpy(scale->w_expr, "iw", sizeof(scale->w_expr)); |
|
97 |
- av_strlcpy(scale->h_expr, "ih", sizeof(scale->h_expr)); |
|
112 |
+ scale->class = &scale_class; |
|
113 |
+ av_opt_set_defaults(scale); |
|
114 |
+ |
|
115 |
+ if ((ret = av_opt_set_from_string(scale, args, shorthand, "=", ":")) < 0) |
|
116 |
+ return ret; |
|
117 |
+ |
|
118 |
+ av_log(ctx, AV_LOG_VERBOSE, "w:%s h:%s flags:%s interl:%d\n", |
|
119 |
+ scale->w_expr, scale->h_expr, scale->flags_str, scale->interlaced); |
|
98 | 120 |
|
99 | 121 |
scale->flags = SWS_BILINEAR; |
100 |
- if (args) { |
|
101 |
- sscanf(args, "%255[^:]:%255[^:]", scale->w_expr, scale->h_expr); |
|
102 |
- p = strstr(args,"flags="); |
|
103 |
- if (p) { |
|
104 |
- const AVClass *class = sws_get_class(); |
|
105 |
- const AVOption *o = av_opt_find(&class, "sws_flags", NULL, 0, |
|
106 |
- AV_OPT_SEARCH_FAKE_OBJ); |
|
107 |
- int ret = av_opt_eval_flags(&class, o, p + 6, &scale->flags); |
|
108 |
- |
|
109 |
- if (ret < 0) |
|
110 |
- return ret; |
|
111 |
- } |
|
112 |
- if(strstr(args,"interl=1")){ |
|
113 |
- scale->interlaced=1; |
|
114 |
- }else if(strstr(args,"interl=-1")) |
|
115 |
- scale->interlaced=-1; |
|
122 |
+ if (scale->flags_str) { |
|
123 |
+ const AVClass *class = sws_get_class(); |
|
124 |
+ const AVOption *o = av_opt_find(&class, "sws_flags", NULL, 0, |
|
125 |
+ AV_OPT_SEARCH_FAKE_OBJ); |
|
126 |
+ int ret = av_opt_eval_flags(&class, o, scale->flags_str, &scale->flags); |
|
127 |
+ if (ret < 0) |
|
128 |
+ return ret; |
|
116 | 129 |
} |
117 | 130 |
|
118 | 131 |
return 0; |
... | ... |
@@ -125,6 +140,7 @@ static av_cold void uninit(AVFilterContext *ctx) |
125 | 125 |
sws_freeContext(scale->isws[0]); |
126 | 126 |
sws_freeContext(scale->isws[1]); |
127 | 127 |
scale->sws = NULL; |
128 |
+ av_opt_free(scale); |
|
128 | 129 |
} |
129 | 130 |
|
130 | 131 |
static int query_formats(AVFilterContext *ctx) |
... | ... |
@@ -283,14 +299,17 @@ static int start_frame(AVFilterLink *link, AVFilterBufferRef *picref) |
283 | 283 |
AVFilterLink *outlink = link->dst->outputs[0]; |
284 | 284 |
AVFilterBufferRef *outpicref, *for_next_filter; |
285 | 285 |
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(link->format); |
286 |
+ char buf[32]; |
|
286 | 287 |
int ret = 0; |
287 | 288 |
|
288 | 289 |
if( picref->video->w != link->w |
289 | 290 |
|| picref->video->h != link->h |
290 | 291 |
|| picref->format != link->format) { |
291 | 292 |
int ret; |
292 |
- snprintf(scale->w_expr, sizeof(scale->w_expr)-1, "%d", outlink->w); |
|
293 |
- snprintf(scale->h_expr, sizeof(scale->h_expr)-1, "%d", outlink->h); |
|
293 |
+ snprintf(buf, sizeof(buf)-1, "%d", outlink->w); |
|
294 |
+ av_opt_set(scale, "w", buf, 0); |
|
295 |
+ snprintf(buf, sizeof(buf)-1, "%d", outlink->h); |
|
296 |
+ av_opt_set(scale, "h", buf, 0); |
|
294 | 297 |
|
295 | 298 |
link->dst->inputs[0]->format = picref->format; |
296 | 299 |
link->dst->inputs[0]->w = picref->video->w; |
... | ... |
@@ -132,7 +132,7 @@ do_lavfi_lavd() { |
132 | 132 |
|
133 | 133 |
do_lavfi_lavd "life" "life=s=40x40:r=5:seed=42:mold=64" -t 2 |
134 | 134 |
do_lavfi_lavd "testsrc" "testsrc=r=7:n=2:d=10" |
135 |
-do_lavfi_lavd "scalenorm" "sws_flags=+accurate_rnd+bitexact;testsrc=s=128x96:d=1:r=5,format=yuv420p[a];testsrc=s=160x120:d=1:r=5[b];[a][b]concat=unsafe=1,scale=::flags=+accurate_rnd+bitexact" |
|
135 |
+do_lavfi_lavd "scalenorm" "sws_flags=+accurate_rnd+bitexact;testsrc=s=128x96:d=1:r=5,format=yuv420p[a];testsrc=s=160x120:d=1:r=5[b];[a][b]concat=unsafe=1,scale=flags=+accurate_rnd+bitexact" |
|
136 | 136 |
|
137 | 137 |
# TODO: add tests for |
138 | 138 |
# direct rendering, |