Add support for named options, and deprecate old "num:den" ambiguous
syntax.
... | ... |
@@ -3250,16 +3250,27 @@ Keep in mind that the sample aspect ratio set by the @code{setsar} |
3250 | 3250 |
filter may be changed by later filters in the filterchain, e.g. if |
3251 | 3251 |
another "setsar" or a "setdar" filter is applied. |
3252 | 3252 |
|
3253 |
-The @code{setdar} and @code{setsar} filters accept a parameter string |
|
3254 |
-which represents the wanted aspect ratio. The parameter can |
|
3255 |
-be a floating point number string, an expression, or a string of the form |
|
3256 |
-@var{num}:@var{den}, where @var{num} and @var{den} are the numerator |
|
3257 |
-and denominator of the aspect ratio. If the parameter is not |
|
3258 |
-specified, it is assumed the value "0:1". |
|
3253 |
+The @code{setdar} and @code{setsar} filters accept a string in the |
|
3254 |
+form @var{num}:@var{den} expressing an aspect ratio, or the following |
|
3255 |
+named options, expressed as a sequence of @var{key}=@var{value} pairs, |
|
3256 |
+separated by ":". |
|
3257 |
+ |
|
3258 |
+@table @option |
|
3259 |
+ |
|
3260 |
+@item r, ratio: |
|
3261 |
+Set the aspect ratio used by the filter. |
|
3262 |
+ |
|
3263 |
+The parameter can be a floating point number string, an expression, or |
|
3264 |
+a string of the form @var{num}:@var{den}, where @var{num} and |
|
3265 |
+@var{den} are the numerator and denominator of the aspect ratio. If |
|
3266 |
+the parameter is not specified, it is assumed the value "0". |
|
3267 |
+In case the form "@var{num}:@var{den}" the @code{:} character should |
|
3268 |
+be escaped. |
|
3269 |
+@end table |
|
3259 | 3270 |
|
3260 | 3271 |
For example to change the display aspect ratio to 16:9, specify: |
3261 | 3272 |
@example |
3262 |
-setdar=16:9 |
|
3273 |
+setdar='16:9' |
|
3263 | 3274 |
@end example |
3264 | 3275 |
|
3265 | 3276 |
The example above is equivalent to: |
... | ... |
@@ -3269,7 +3280,7 @@ setdar=1.77777 |
3269 | 3269 |
|
3270 | 3270 |
To change the sample aspect ratio to 10:11, specify: |
3271 | 3271 |
@example |
3272 |
-setsar=10:11 |
|
3272 |
+setsar='10:11' |
|
3273 | 3273 |
@end example |
3274 | 3274 |
|
3275 | 3275 |
@section setfield |
... | ... |
@@ -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 102 |
|
33 |
+#define LIBAVFILTER_VERSION_MICRO 103 |
|
34 | 34 |
|
35 | 35 |
#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ |
36 | 36 |
LIBAVFILTER_VERSION_MINOR, \ |
... | ... |
@@ -24,6 +24,7 @@ |
24 | 24 |
*/ |
25 | 25 |
|
26 | 26 |
#include "libavutil/common.h" |
27 |
+#include "libavutil/opt.h" |
|
27 | 28 |
#include "libavutil/mathematics.h" |
28 | 29 |
#include "libavutil/parseutils.h" |
29 | 30 |
#include "avfilter.h" |
... | ... |
@@ -31,19 +32,44 @@ |
31 | 31 |
#include "video.h" |
32 | 32 |
|
33 | 33 |
typedef struct { |
34 |
+ const AVClass *class; |
|
34 | 35 |
AVRational ratio; |
36 |
+ char *ratio_str; |
|
35 | 37 |
} AspectContext; |
36 | 38 |
|
37 |
-static av_cold int init(AVFilterContext *ctx, const char *args) |
|
39 |
+#define OFFSET(x) offsetof(AspectContext, x) |
|
40 |
+#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM |
|
41 |
+ |
|
42 |
+static const AVOption options[] = { |
|
43 |
+ {"ratio", "set ratio", OFFSET(ratio_str), AV_OPT_TYPE_STRING, {.str="0"}, 0, 0, FLAGS }, |
|
44 |
+ {"r", "set ratio", OFFSET(ratio_str), AV_OPT_TYPE_STRING, {.str="0"}, 0, 0, FLAGS }, |
|
45 |
+ {NULL} |
|
46 |
+}; |
|
47 |
+ |
|
48 |
+static av_cold int init(AVFilterContext *ctx, const char *args, const AVClass *class) |
|
38 | 49 |
{ |
39 | 50 |
AspectContext *aspect = ctx->priv; |
40 |
- aspect->ratio = (AVRational) {0, 1}; |
|
51 |
+ static const char *shorthand[] = { "ratio", NULL }; |
|
52 |
+ char c; |
|
53 |
+ int ret; |
|
54 |
+ AVRational q; |
|
55 |
+ |
|
56 |
+ aspect->class = class; |
|
57 |
+ av_opt_set_defaults(aspect); |
|
58 |
+ |
|
59 |
+ if (sscanf(args, "%d:%d%c", &q.num, &q.den, &c) == 2) { |
|
60 |
+ aspect->ratio_str = av_strdup(args); |
|
61 |
+ av_log(ctx, AV_LOG_WARNING, |
|
62 |
+ "num:den syntax is deprecated, please use num/den or named options instead\n"); |
|
63 |
+ } else if ((ret = av_opt_set_from_string(aspect, args, shorthand, "=", ":")) < 0) { |
|
64 |
+ return ret; |
|
65 |
+ } |
|
41 | 66 |
|
42 |
- if (args) { |
|
43 |
- if (av_parse_ratio(&aspect->ratio, args, 100, 0, ctx) < 0 || |
|
44 |
- aspect->ratio.num < 0 || aspect->ratio.den <= 0) { |
|
67 |
+ if (aspect->ratio_str) { |
|
68 |
+ ret = av_parse_ratio(&aspect->ratio, aspect->ratio_str, 100, 0, ctx); |
|
69 |
+ if (ret < 0 || aspect->ratio.num < 0 || aspect->ratio.den <= 0) { |
|
45 | 70 |
av_log(ctx, AV_LOG_ERROR, |
46 |
- "Invalid string '%s' for aspect ratio.\n", args); |
|
71 |
+ "Invalid string '%s' for aspect ratio\n", args); |
|
47 | 72 |
return AVERROR(EINVAL); |
48 | 73 |
} |
49 | 74 |
} |
... | ... |
@@ -61,7 +87,23 @@ static int start_frame(AVFilterLink *link, AVFilterBufferRef *picref) |
61 | 61 |
return ff_start_frame(link->dst->outputs[0], picref); |
62 | 62 |
} |
63 | 63 |
|
64 |
+static av_cold void uninit(AVFilterContext *ctx) |
|
65 |
+{ |
|
66 |
+ AspectContext *aspect = ctx->priv; |
|
67 |
+ |
|
68 |
+ av_opt_free(aspect); |
|
69 |
+} |
|
70 |
+ |
|
64 | 71 |
#if CONFIG_SETDAR_FILTER |
72 |
+ |
|
73 |
+#define setdar_options options |
|
74 |
+AVFILTER_DEFINE_CLASS(setdar); |
|
75 |
+ |
|
76 |
+static av_cold int setdar_init(AVFilterContext *ctx, const char *args) |
|
77 |
+{ |
|
78 |
+ return init(ctx, args, &setdar_class); |
|
79 |
+} |
|
80 |
+ |
|
65 | 81 |
static int setdar_config_props(AVFilterLink *inlink) |
66 | 82 |
{ |
67 | 83 |
AspectContext *aspect = inlink->dst->priv; |
... | ... |
@@ -103,17 +145,29 @@ AVFilter avfilter_vf_setdar = { |
103 | 103 |
.name = "setdar", |
104 | 104 |
.description = NULL_IF_CONFIG_SMALL("Set the frame display aspect ratio."), |
105 | 105 |
|
106 |
- .init = init, |
|
106 |
+ .init = setdar_init, |
|
107 |
+ .uninit = uninit, |
|
107 | 108 |
|
108 | 109 |
.priv_size = sizeof(AspectContext), |
109 | 110 |
|
110 | 111 |
.inputs = avfilter_vf_setdar_inputs, |
111 | 112 |
|
112 | 113 |
.outputs = avfilter_vf_setdar_outputs, |
114 |
+ .priv_class = &setdar_class, |
|
113 | 115 |
}; |
116 |
+ |
|
114 | 117 |
#endif /* CONFIG_SETDAR_FILTER */ |
115 | 118 |
|
116 | 119 |
#if CONFIG_SETSAR_FILTER |
120 |
+ |
|
121 |
+#define setsar_options options |
|
122 |
+AVFILTER_DEFINE_CLASS(setsar); |
|
123 |
+ |
|
124 |
+static av_cold int setsar_init(AVFilterContext *ctx, const char *args) |
|
125 |
+{ |
|
126 |
+ return init(ctx, args, &setsar_class); |
|
127 |
+} |
|
128 |
+ |
|
117 | 129 |
static int setsar_config_props(AVFilterLink *inlink) |
118 | 130 |
{ |
119 | 131 |
AspectContext *aspect = inlink->dst->priv; |
... | ... |
@@ -147,12 +201,15 @@ AVFilter avfilter_vf_setsar = { |
147 | 147 |
.name = "setsar", |
148 | 148 |
.description = NULL_IF_CONFIG_SMALL("Set the pixel sample aspect ratio."), |
149 | 149 |
|
150 |
- .init = init, |
|
150 |
+ .init = setsar_init, |
|
151 |
+ .uninit = uninit, |
|
151 | 152 |
|
152 | 153 |
.priv_size = sizeof(AspectContext), |
153 | 154 |
|
154 | 155 |
.inputs = avfilter_vf_setsar_inputs, |
155 | 156 |
|
156 | 157 |
.outputs = avfilter_vf_setsar_outputs, |
158 |
+ .priv_class = &setdar_class, |
|
157 | 159 |
}; |
160 |
+ |
|
158 | 161 |
#endif /* CONFIG_SETSAR_FILTER */ |