Example: -vf setsar=sar="sar*9/10"
Signed-off-by: Rudolf Polzer <divverent@xonotic.org>
Signed-off-by: Anton Khirnov <anton@khirnov.net>
... | ... |
@@ -45,6 +45,7 @@ version 10: |
45 | 45 |
- raw HEVC, HEVC in MOV/MP4, HEVC in Matroska, HEVC in MPEG-TS demuxing |
46 | 46 |
- remove avplay -vismv option, which has not worked for a long time |
47 | 47 |
- Live HDS muxer |
48 |
+- setsar/setdar filters now support variables in ratio expressions |
|
48 | 49 |
|
49 | 50 |
|
50 | 51 |
version 9: |
... | ... |
@@ -2049,10 +2049,35 @@ This filter accepts the following options: |
2049 | 2049 |
@table @option |
2050 | 2050 |
|
2051 | 2051 |
@item dar |
2052 |
-Output display aspect ratio, as a rational or a decimal number. |
|
2052 |
+Output display aspect ratio. |
|
2053 | 2053 |
|
2054 | 2054 |
@end table |
2055 | 2055 |
|
2056 |
+The parameter @var{dar} is an expression containing |
|
2057 |
+the following constants: |
|
2058 |
+ |
|
2059 |
+@table @option |
|
2060 |
+@item E, PI, PHI |
|
2061 |
+the corresponding mathematical approximated values for e |
|
2062 |
+(euler number), pi (greek PI), phi (golden ratio) |
|
2063 |
+ |
|
2064 |
+@item w, h |
|
2065 |
+the input width and height |
|
2066 |
+ |
|
2067 |
+@item a |
|
2068 |
+same as @var{w} / @var{h} |
|
2069 |
+ |
|
2070 |
+@item sar |
|
2071 |
+input sample aspect ratio |
|
2072 |
+ |
|
2073 |
+@item dar |
|
2074 |
+input display aspect ratio, it is the same as (@var{w} / @var{h}) * @var{sar} |
|
2075 |
+ |
|
2076 |
+@item hsub, vsub |
|
2077 |
+horizontal and vertical chroma subsample values. For example for the |
|
2078 |
+pixel format "yuv422p" @var{hsub} is 2 and @var{vsub} is 1. |
|
2079 |
+@end table |
|
2080 |
+ |
|
2056 | 2081 |
For example to change the display aspect ratio to 16:9, specify: |
2057 | 2082 |
@example |
2058 | 2083 |
setdar=dar=16/9 |
... | ... |
@@ -2158,10 +2183,35 @@ This filter accepts the following options: |
2158 | 2158 |
@table @option |
2159 | 2159 |
|
2160 | 2160 |
@item sar |
2161 |
-Output sample aspect ratio, as a rational or decimal number. |
|
2161 |
+Output sample aspect ratio. |
|
2162 | 2162 |
|
2163 | 2163 |
@end table |
2164 | 2164 |
|
2165 |
+The parameter @var{sar} is an expression containing |
|
2166 |
+the following constants: |
|
2167 |
+ |
|
2168 |
+@table @option |
|
2169 |
+@item E, PI, PHI |
|
2170 |
+the corresponding mathematical approximated values for e |
|
2171 |
+(euler number), pi (greek PI), phi (golden ratio) |
|
2172 |
+ |
|
2173 |
+@item w, h |
|
2174 |
+the input width and height |
|
2175 |
+ |
|
2176 |
+@item a |
|
2177 |
+same as @var{w} / @var{h} |
|
2178 |
+ |
|
2179 |
+@item sar |
|
2180 |
+input sample aspect ratio |
|
2181 |
+ |
|
2182 |
+@item dar |
|
2183 |
+input display aspect ratio, it is the same as (@var{w} / @var{h}) * @var{sar} |
|
2184 |
+ |
|
2185 |
+@item hsub, vsub |
|
2186 |
+horizontal and vertical chroma subsample values. For example for the |
|
2187 |
+pixel format "yuv422p" @var{hsub} is 2 and @var{vsub} is 1. |
|
2188 |
+@end table |
|
2189 |
+ |
|
2165 | 2190 |
For example to change the sample aspect ratio to 10:11, specify: |
2166 | 2191 |
@example |
2167 | 2192 |
setsar=sar=10/11 |
... | ... |
@@ -26,13 +26,42 @@ |
26 | 26 |
#include <float.h> |
27 | 27 |
|
28 | 28 |
#include "libavutil/common.h" |
29 |
+#include "libavutil/eval.h" |
|
29 | 30 |
#include "libavutil/mathematics.h" |
30 | 31 |
#include "libavutil/opt.h" |
32 |
+#include "libavutil/parseutils.h" |
|
33 |
+#include "libavutil/pixdesc.h" |
|
31 | 34 |
|
32 | 35 |
#include "avfilter.h" |
33 | 36 |
#include "internal.h" |
34 | 37 |
#include "video.h" |
35 | 38 |
|
39 |
+static const char *const var_names[] = { |
|
40 |
+ "PI", |
|
41 |
+ "PHI", |
|
42 |
+ "E", |
|
43 |
+ "w", |
|
44 |
+ "h", |
|
45 |
+ "a", "dar", |
|
46 |
+ "sar", |
|
47 |
+ "hsub", |
|
48 |
+ "vsub", |
|
49 |
+ NULL |
|
50 |
+}; |
|
51 |
+ |
|
52 |
+enum var_name { |
|
53 |
+ VAR_PI, |
|
54 |
+ VAR_PHI, |
|
55 |
+ VAR_E, |
|
56 |
+ VAR_W, |
|
57 |
+ VAR_H, |
|
58 |
+ VAR_A, VAR_DAR, |
|
59 |
+ VAR_SAR, |
|
60 |
+ VAR_HSUB, |
|
61 |
+ VAR_VSUB, |
|
62 |
+ VARS_NB |
|
63 |
+}; |
|
64 |
+ |
|
36 | 65 |
typedef struct { |
37 | 66 |
const AVClass *class; |
38 | 67 |
AVRational dar; |
... | ... |
@@ -40,6 +69,7 @@ typedef struct { |
40 | 40 |
#if FF_API_OLD_FILTER_OPTS |
41 | 41 |
float aspect_num, aspect_den; |
42 | 42 |
#endif |
43 |
+ char *ratio_expr; |
|
43 | 44 |
} AspectContext; |
44 | 45 |
|
45 | 46 |
#if FF_API_OLD_FILTER_OPTS |
... | ... |
@@ -68,12 +98,54 @@ static int filter_frame(AVFilterLink *link, AVFrame *frame) |
68 | 68 |
#define OFFSET(x) offsetof(AspectContext, x) |
69 | 69 |
#define FLAGS AV_OPT_FLAG_VIDEO_PARAM |
70 | 70 |
|
71 |
+static int get_aspect_ratio(AVFilterLink *inlink, AVRational *aspect_ratio) |
|
72 |
+{ |
|
73 |
+ AVFilterContext *ctx = inlink->dst; |
|
74 |
+ AspectContext *s = inlink->dst->priv; |
|
75 |
+ const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format); |
|
76 |
+ double var_values[VARS_NB], res; |
|
77 |
+ int ret; |
|
78 |
+ |
|
79 |
+ var_values[VAR_PI] = M_PI; |
|
80 |
+ var_values[VAR_PHI] = M_PHI; |
|
81 |
+ var_values[VAR_E] = M_E; |
|
82 |
+ var_values[VAR_W] = inlink->w; |
|
83 |
+ var_values[VAR_H] = inlink->h; |
|
84 |
+ var_values[VAR_A] = (double) inlink->w / inlink->h; |
|
85 |
+ var_values[VAR_SAR] = inlink->sample_aspect_ratio.num ? |
|
86 |
+ (double) inlink->sample_aspect_ratio.num / inlink->sample_aspect_ratio.den : 1; |
|
87 |
+ var_values[VAR_DAR] = var_values[VAR_A] * var_values[VAR_SAR]; |
|
88 |
+ var_values[VAR_HSUB] = 1 << desc->log2_chroma_w; |
|
89 |
+ var_values[VAR_VSUB] = 1 << desc->log2_chroma_h; |
|
90 |
+ |
|
91 |
+ /* evaluate new aspect ratio*/ |
|
92 |
+ if ((ret = av_expr_parse_and_eval(&res, s->ratio_expr, |
|
93 |
+ var_names, var_values, |
|
94 |
+ NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0) { |
|
95 |
+ av_log(NULL, AV_LOG_ERROR, |
|
96 |
+ "Error when evaluating the expression '%s'\n", s->ratio_expr); |
|
97 |
+ return ret; |
|
98 |
+ } |
|
99 |
+ *aspect_ratio = av_d2q(res, INT_MAX); |
|
100 |
+ return 0; |
|
101 |
+} |
|
102 |
+ |
|
71 | 103 |
#if CONFIG_SETDAR_FILTER |
72 | 104 |
/* for setdar filter, convert from frame aspect ratio to pixel aspect ratio */ |
73 | 105 |
static int setdar_config_props(AVFilterLink *inlink) |
74 | 106 |
{ |
75 | 107 |
AspectContext *s = inlink->dst->priv; |
76 | 108 |
AVRational dar; |
109 |
+ int ret; |
|
110 |
+ |
|
111 |
+#if FF_API_OLD_FILTER_OPTS |
|
112 |
+ if (!(s->aspect_num > 0 && s->aspect_den > 0)) { |
|
113 |
+#endif |
|
114 |
+ if ((ret = get_aspect_ratio(inlink, &s->dar))) |
|
115 |
+ return ret; |
|
116 |
+#if FF_API_OLD_FILTER_OPTS |
|
117 |
+ } |
|
118 |
+#endif |
|
77 | 119 |
|
78 | 120 |
if (s->dar.num && s->dar.den) { |
79 | 121 |
av_reduce(&s->sar.num, &s->sar.den, |
... | ... |
@@ -98,7 +170,7 @@ static const AVOption setdar_options[] = { |
98 | 98 |
{ "dar_num", NULL, OFFSET(aspect_num), AV_OPT_TYPE_FLOAT, { .dbl = 0 }, 0, FLT_MAX, FLAGS }, |
99 | 99 |
{ "dar_den", NULL, OFFSET(aspect_den), AV_OPT_TYPE_FLOAT, { .dbl = 0 }, 0, FLT_MAX, FLAGS }, |
100 | 100 |
#endif |
101 |
- { "dar", "display aspect ratio", OFFSET(dar), AV_OPT_TYPE_RATIONAL, { .dbl = 0 }, 0, INT_MAX, FLAGS }, |
|
101 |
+ { "dar", "display aspect ratio", OFFSET(ratio_expr), AV_OPT_TYPE_STRING, { .str = "1" }, .flags = FLAGS }, |
|
102 | 102 |
{ NULL }, |
103 | 103 |
}; |
104 | 104 |
|
... | ... |
@@ -150,6 +222,16 @@ AVFilter ff_vf_setdar = { |
150 | 150 |
static int setsar_config_props(AVFilterLink *inlink) |
151 | 151 |
{ |
152 | 152 |
AspectContext *s = inlink->dst->priv; |
153 |
+ int ret; |
|
154 |
+ |
|
155 |
+#if FF_API_OLD_FILTER_OPTS |
|
156 |
+ if (!(s->aspect_num > 0 && s->aspect_den > 0)) { |
|
157 |
+#endif |
|
158 |
+ if ((ret = get_aspect_ratio(inlink, &s->sar))) |
|
159 |
+ return ret; |
|
160 |
+#if FF_API_OLD_FILTER_OPTS |
|
161 |
+ } |
|
162 |
+#endif |
|
153 | 163 |
|
154 | 164 |
inlink->sample_aspect_ratio = s->sar; |
155 | 165 |
|
... | ... |
@@ -161,7 +243,7 @@ static const AVOption setsar_options[] = { |
161 | 161 |
{ "sar_num", NULL, OFFSET(aspect_num), AV_OPT_TYPE_FLOAT, { .dbl = 0 }, 0, FLT_MAX, FLAGS }, |
162 | 162 |
{ "sar_den", NULL, OFFSET(aspect_den), AV_OPT_TYPE_FLOAT, { .dbl = 0 }, 0, FLT_MAX, FLAGS }, |
163 | 163 |
#endif |
164 |
- { "sar", "sample (pixel) aspect ratio", OFFSET(sar), AV_OPT_TYPE_RATIONAL, { .dbl = 1 }, 0, INT_MAX, FLAGS }, |
|
164 |
+ { "sar", "sample (pixel) aspect ratio", OFFSET(ratio_expr), AV_OPT_TYPE_STRING, { .str = "1" }, .flags = FLAGS }, |
|
165 | 165 |
{ NULL }, |
166 | 166 |
}; |
167 | 167 |
|