Line | Branch | Exec | Source |
---|---|---|---|
1 | /* | ||
2 | * Copyright (c) 2007 Bobby Bingham | ||
3 | * | ||
4 | * This file is part of FFmpeg. | ||
5 | * | ||
6 | * FFmpeg is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU Lesser General Public | ||
8 | * License as published by the Free Software Foundation; either | ||
9 | * version 2.1 of the License, or (at your option) any later version. | ||
10 | * | ||
11 | * FFmpeg is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
14 | * Lesser General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU Lesser General Public | ||
17 | * License along with FFmpeg; if not, write to the Free Software | ||
18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file | ||
23 | * scale video filter | ||
24 | */ | ||
25 | |||
26 | #include <float.h> | ||
27 | #include <stdio.h> | ||
28 | #include <string.h> | ||
29 | |||
30 | #include "avfilter.h" | ||
31 | #include "filters.h" | ||
32 | #include "formats.h" | ||
33 | #include "framesync.h" | ||
34 | #include "libavutil/pixfmt.h" | ||
35 | #include "scale_eval.h" | ||
36 | #include "video.h" | ||
37 | #include "libavutil/eval.h" | ||
38 | #include "libavutil/imgutils_internal.h" | ||
39 | #include "libavutil/internal.h" | ||
40 | #include "libavutil/mem.h" | ||
41 | #include "libavutil/opt.h" | ||
42 | #include "libavutil/parseutils.h" | ||
43 | #include "libavutil/pixdesc.h" | ||
44 | #include "libswscale/swscale.h" | ||
45 | |||
46 | static const char *const var_names[] = { | ||
47 | "in_w", "iw", | ||
48 | "in_h", "ih", | ||
49 | "out_w", "ow", | ||
50 | "out_h", "oh", | ||
51 | "a", | ||
52 | "sar", | ||
53 | "dar", | ||
54 | "hsub", | ||
55 | "vsub", | ||
56 | "ohsub", | ||
57 | "ovsub", | ||
58 | "n", | ||
59 | "t", | ||
60 | #if FF_API_FRAME_PKT | ||
61 | "pos", | ||
62 | #endif | ||
63 | "ref_w", "rw", | ||
64 | "ref_h", "rh", | ||
65 | "ref_a", | ||
66 | "ref_sar", | ||
67 | "ref_dar", "rdar", | ||
68 | "ref_hsub", | ||
69 | "ref_vsub", | ||
70 | "ref_n", | ||
71 | "ref_t", | ||
72 | "ref_pos", | ||
73 | /* Legacy variables for scale2ref */ | ||
74 | "main_w", | ||
75 | "main_h", | ||
76 | "main_a", | ||
77 | "main_sar", | ||
78 | "main_dar", "mdar", | ||
79 | "main_hsub", | ||
80 | "main_vsub", | ||
81 | "main_n", | ||
82 | "main_t", | ||
83 | "main_pos", | ||
84 | NULL | ||
85 | }; | ||
86 | |||
87 | enum var_name { | ||
88 | VAR_IN_W, VAR_IW, | ||
89 | VAR_IN_H, VAR_IH, | ||
90 | VAR_OUT_W, VAR_OW, | ||
91 | VAR_OUT_H, VAR_OH, | ||
92 | VAR_A, | ||
93 | VAR_SAR, | ||
94 | VAR_DAR, | ||
95 | VAR_HSUB, | ||
96 | VAR_VSUB, | ||
97 | VAR_OHSUB, | ||
98 | VAR_OVSUB, | ||
99 | VAR_N, | ||
100 | VAR_T, | ||
101 | #if FF_API_FRAME_PKT | ||
102 | VAR_POS, | ||
103 | #endif | ||
104 | VAR_REF_W, VAR_RW, | ||
105 | VAR_REF_H, VAR_RH, | ||
106 | VAR_REF_A, | ||
107 | VAR_REF_SAR, | ||
108 | VAR_REF_DAR, VAR_RDAR, | ||
109 | VAR_REF_HSUB, | ||
110 | VAR_REF_VSUB, | ||
111 | VAR_REF_N, | ||
112 | VAR_REF_T, | ||
113 | VAR_REF_POS, | ||
114 | VAR_S2R_MAIN_W, | ||
115 | VAR_S2R_MAIN_H, | ||
116 | VAR_S2R_MAIN_A, | ||
117 | VAR_S2R_MAIN_SAR, | ||
118 | VAR_S2R_MAIN_DAR, VAR_S2R_MDAR, | ||
119 | VAR_S2R_MAIN_HSUB, | ||
120 | VAR_S2R_MAIN_VSUB, | ||
121 | VAR_S2R_MAIN_N, | ||
122 | VAR_S2R_MAIN_T, | ||
123 | VAR_S2R_MAIN_POS, | ||
124 | VARS_NB | ||
125 | }; | ||
126 | |||
127 | enum EvalMode { | ||
128 | EVAL_MODE_INIT, | ||
129 | EVAL_MODE_FRAME, | ||
130 | EVAL_MODE_NB | ||
131 | }; | ||
132 | |||
133 | typedef struct ScaleContext { | ||
134 | const AVClass *class; | ||
135 | SwsContext *sws; | ||
136 | FFFrameSync fs; | ||
137 | |||
138 | /** | ||
139 | * New dimensions. Special values are: | ||
140 | * 0 = original width/height | ||
141 | * -1 = keep original aspect | ||
142 | * -N = try to keep aspect but make sure it is divisible by N | ||
143 | */ | ||
144 | int w, h; | ||
145 | char *size_str; | ||
146 | double param[2]; // sws params | ||
147 | |||
148 | int hsub, vsub; ///< chroma subsampling | ||
149 | int slice_y; ///< top of current output slice | ||
150 | int interlaced; | ||
151 | int uses_ref; | ||
152 | |||
153 | char *w_expr; ///< width expression string | ||
154 | char *h_expr; ///< height expression string | ||
155 | AVExpr *w_pexpr; | ||
156 | AVExpr *h_pexpr; | ||
157 | double var_values[VARS_NB]; | ||
158 | |||
159 | char *flags_str; | ||
160 | |||
161 | int in_color_matrix; | ||
162 | int out_color_matrix; | ||
163 | int in_primaries; | ||
164 | int out_primaries; | ||
165 | int in_transfer; | ||
166 | int out_transfer; | ||
167 | int in_range; | ||
168 | int out_range; | ||
169 | |||
170 | int in_chroma_loc; | ||
171 | int out_chroma_loc; | ||
172 | int out_h_chr_pos; | ||
173 | int out_v_chr_pos; | ||
174 | int in_h_chr_pos; | ||
175 | int in_v_chr_pos; | ||
176 | |||
177 | int force_original_aspect_ratio; | ||
178 | int force_divisible_by; | ||
179 | int reset_sar; | ||
180 | |||
181 | int eval_mode; ///< expression evaluation mode | ||
182 | |||
183 | } ScaleContext; | ||
184 | |||
185 | const FFFilter ff_vf_scale2ref; | ||
186 | #define IS_SCALE2REF(ctx) ((ctx)->filter == &ff_vf_scale2ref.p) | ||
187 | |||
188 | static int config_props(AVFilterLink *outlink); | ||
189 | |||
190 | 19846 | static int check_exprs(AVFilterContext *ctx) | |
191 | { | ||
192 | 19846 | ScaleContext *scale = ctx->priv; | |
193 | 19846 | unsigned vars_w[VARS_NB] = { 0 }, vars_h[VARS_NB] = { 0 }; | |
194 | |||
195 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 19846 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
19846 | if (!scale->w_pexpr && !scale->h_pexpr) |
196 | ✗ | return AVERROR(EINVAL); | |
197 | |||
198 |
1/2✓ Branch 0 taken 19846 times.
✗ Branch 1 not taken.
|
19846 | if (scale->w_pexpr) |
199 | 19846 | av_expr_count_vars(scale->w_pexpr, vars_w, VARS_NB); | |
200 |
2/2✓ Branch 0 taken 9940 times.
✓ Branch 1 taken 9906 times.
|
19846 | if (scale->h_pexpr) |
201 | 9940 | av_expr_count_vars(scale->h_pexpr, vars_h, VARS_NB); | |
202 | |||
203 |
2/4✓ Branch 0 taken 19846 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 19846 times.
|
19846 | if (vars_w[VAR_OUT_W] || vars_w[VAR_OW]) { |
204 | ✗ | av_log(ctx, AV_LOG_ERROR, "Width expression cannot be self-referencing: '%s'.\n", scale->w_expr); | |
205 | ✗ | return AVERROR(EINVAL); | |
206 | } | ||
207 | |||
208 |
2/4✓ Branch 0 taken 19846 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 19846 times.
|
19846 | if (vars_h[VAR_OUT_H] || vars_h[VAR_OH]) { |
209 | ✗ | av_log(ctx, AV_LOG_ERROR, "Height expression cannot be self-referencing: '%s'.\n", scale->h_expr); | |
210 | ✗ | return AVERROR(EINVAL); | |
211 | } | ||
212 | |||
213 |
2/4✓ Branch 0 taken 19846 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 19846 times.
|
19846 | if ((vars_w[VAR_OUT_H] || vars_w[VAR_OH]) && |
214 | ✗ | (vars_h[VAR_OUT_W] || vars_h[VAR_OW])) { | |
215 | ✗ | av_log(ctx, AV_LOG_WARNING, "Circular references detected for width '%s' and height '%s' - possibly invalid.\n", scale->w_expr, scale->h_expr); | |
216 | } | ||
217 | |||
218 |
2/4✓ Branch 0 taken 19846 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 19846 times.
✗ Branch 3 not taken.
|
19846 | if (vars_w[VAR_REF_W] || vars_h[VAR_REF_W] || |
219 |
3/4✓ Branch 0 taken 19842 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 19842 times.
✗ Branch 3 not taken.
|
19846 | vars_w[VAR_RW] || vars_h[VAR_RW] || |
220 |
2/4✓ Branch 0 taken 19842 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 19842 times.
✗ Branch 3 not taken.
|
19842 | vars_w[VAR_REF_H] || vars_h[VAR_REF_H] || |
221 |
2/4✓ Branch 0 taken 19842 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 19842 times.
✗ Branch 3 not taken.
|
19842 | vars_w[VAR_RH] || vars_h[VAR_RH] || |
222 |
2/4✓ Branch 0 taken 19842 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 19842 times.
✗ Branch 3 not taken.
|
19842 | vars_w[VAR_REF_A] || vars_h[VAR_REF_A] || |
223 |
2/4✓ Branch 0 taken 19842 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 19842 times.
✗ Branch 3 not taken.
|
19842 | vars_w[VAR_REF_SAR] || vars_h[VAR_REF_SAR] || |
224 |
2/4✓ Branch 0 taken 19842 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 19842 times.
✗ Branch 3 not taken.
|
19842 | vars_w[VAR_REF_DAR] || vars_h[VAR_REF_DAR] || |
225 |
2/4✓ Branch 0 taken 19842 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 19842 times.
✗ Branch 3 not taken.
|
19842 | vars_w[VAR_RDAR] || vars_h[VAR_RDAR] || |
226 |
2/4✓ Branch 0 taken 19842 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 19842 times.
✗ Branch 3 not taken.
|
19842 | vars_w[VAR_REF_HSUB] || vars_h[VAR_REF_HSUB] || |
227 |
2/4✓ Branch 0 taken 19842 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 19842 times.
✗ Branch 3 not taken.
|
19842 | vars_w[VAR_REF_VSUB] || vars_h[VAR_REF_VSUB] || |
228 |
2/4✓ Branch 0 taken 19842 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 19842 times.
✗ Branch 3 not taken.
|
19842 | vars_w[VAR_REF_N] || vars_h[VAR_REF_N] || |
229 |
2/4✓ Branch 0 taken 19842 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 19842 times.
✗ Branch 3 not taken.
|
19842 | vars_w[VAR_REF_T] || vars_h[VAR_REF_T] || |
230 |
2/4✓ Branch 0 taken 19842 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 19842 times.
|
19842 | vars_w[VAR_REF_POS] || vars_h[VAR_REF_POS]) { |
231 | 4 | scale->uses_ref = 1; | |
232 | } | ||
233 | |||
234 |
1/2✓ Branch 0 taken 19846 times.
✗ Branch 1 not taken.
|
19846 | if (!IS_SCALE2REF(ctx) && |
235 |
2/4✓ Branch 0 taken 19846 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 19846 times.
✗ Branch 3 not taken.
|
19846 | (vars_w[VAR_S2R_MAIN_W] || vars_h[VAR_S2R_MAIN_W] || |
236 |
2/4✓ Branch 0 taken 19846 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 19846 times.
✗ Branch 3 not taken.
|
19846 | vars_w[VAR_S2R_MAIN_H] || vars_h[VAR_S2R_MAIN_H] || |
237 |
2/4✓ Branch 0 taken 19846 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 19846 times.
✗ Branch 3 not taken.
|
19846 | vars_w[VAR_S2R_MAIN_A] || vars_h[VAR_S2R_MAIN_A] || |
238 |
2/4✓ Branch 0 taken 19846 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 19846 times.
✗ Branch 3 not taken.
|
19846 | vars_w[VAR_S2R_MAIN_SAR] || vars_h[VAR_S2R_MAIN_SAR] || |
239 |
2/4✓ Branch 0 taken 19846 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 19846 times.
✗ Branch 3 not taken.
|
19846 | vars_w[VAR_S2R_MAIN_DAR] || vars_h[VAR_S2R_MAIN_DAR] || |
240 |
2/4✓ Branch 0 taken 19846 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 19846 times.
✗ Branch 3 not taken.
|
19846 | vars_w[VAR_S2R_MDAR] || vars_h[VAR_S2R_MDAR] || |
241 |
2/4✓ Branch 0 taken 19846 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 19846 times.
✗ Branch 3 not taken.
|
19846 | vars_w[VAR_S2R_MAIN_HSUB] || vars_h[VAR_S2R_MAIN_HSUB] || |
242 |
2/4✓ Branch 0 taken 19846 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 19846 times.
✗ Branch 3 not taken.
|
19846 | vars_w[VAR_S2R_MAIN_VSUB] || vars_h[VAR_S2R_MAIN_VSUB] || |
243 |
2/4✓ Branch 0 taken 19846 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 19846 times.
✗ Branch 3 not taken.
|
19846 | vars_w[VAR_S2R_MAIN_N] || vars_h[VAR_S2R_MAIN_N] || |
244 |
2/4✓ Branch 0 taken 19846 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 19846 times.
✗ Branch 3 not taken.
|
19846 | vars_w[VAR_S2R_MAIN_T] || vars_h[VAR_S2R_MAIN_T] || |
245 |
2/4✓ Branch 0 taken 19846 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 19846 times.
|
19846 | vars_w[VAR_S2R_MAIN_POS] || vars_h[VAR_S2R_MAIN_POS]) ) { |
246 | ✗ | av_log(ctx, AV_LOG_ERROR, "Expressions with scale2ref variables are not valid in scale filter.\n"); | |
247 | ✗ | return AVERROR(EINVAL); | |
248 | } | ||
249 | |||
250 |
1/2✓ Branch 0 taken 19846 times.
✗ Branch 1 not taken.
|
19846 | if (!IS_SCALE2REF(ctx) && |
251 |
2/4✓ Branch 0 taken 19846 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 19846 times.
✗ Branch 3 not taken.
|
19846 | (vars_w[VAR_S2R_MAIN_W] || vars_h[VAR_S2R_MAIN_W] || |
252 |
2/4✓ Branch 0 taken 19846 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 19846 times.
✗ Branch 3 not taken.
|
19846 | vars_w[VAR_S2R_MAIN_H] || vars_h[VAR_S2R_MAIN_H] || |
253 |
2/4✓ Branch 0 taken 19846 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 19846 times.
✗ Branch 3 not taken.
|
19846 | vars_w[VAR_S2R_MAIN_A] || vars_h[VAR_S2R_MAIN_A] || |
254 |
2/4✓ Branch 0 taken 19846 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 19846 times.
✗ Branch 3 not taken.
|
19846 | vars_w[VAR_S2R_MAIN_SAR] || vars_h[VAR_S2R_MAIN_SAR] || |
255 |
2/4✓ Branch 0 taken 19846 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 19846 times.
✗ Branch 3 not taken.
|
19846 | vars_w[VAR_S2R_MAIN_DAR] || vars_h[VAR_S2R_MAIN_DAR] || |
256 |
2/4✓ Branch 0 taken 19846 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 19846 times.
✗ Branch 3 not taken.
|
19846 | vars_w[VAR_S2R_MDAR] || vars_h[VAR_S2R_MDAR] || |
257 |
2/4✓ Branch 0 taken 19846 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 19846 times.
✗ Branch 3 not taken.
|
19846 | vars_w[VAR_S2R_MAIN_HSUB] || vars_h[VAR_S2R_MAIN_HSUB] || |
258 |
2/4✓ Branch 0 taken 19846 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 19846 times.
✗ Branch 3 not taken.
|
19846 | vars_w[VAR_S2R_MAIN_VSUB] || vars_h[VAR_S2R_MAIN_VSUB] || |
259 |
2/4✓ Branch 0 taken 19846 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 19846 times.
✗ Branch 3 not taken.
|
19846 | vars_w[VAR_S2R_MAIN_N] || vars_h[VAR_S2R_MAIN_N] || |
260 |
2/4✓ Branch 0 taken 19846 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 19846 times.
✗ Branch 3 not taken.
|
19846 | vars_w[VAR_S2R_MAIN_T] || vars_h[VAR_S2R_MAIN_T] || |
261 |
2/4✓ Branch 0 taken 19846 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 19846 times.
|
19846 | vars_w[VAR_S2R_MAIN_POS] || vars_h[VAR_S2R_MAIN_POS]) ) { |
262 | ✗ | av_log(ctx, AV_LOG_ERROR, "Expressions with scale2ref variables are not valid in scale filter.\n"); | |
263 | ✗ | return AVERROR(EINVAL); | |
264 | } | ||
265 | |||
266 |
1/2✓ Branch 0 taken 19846 times.
✗ Branch 1 not taken.
|
19846 | if (scale->eval_mode == EVAL_MODE_INIT && |
267 |
2/4✓ Branch 0 taken 19846 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 19846 times.
✗ Branch 3 not taken.
|
19846 | (vars_w[VAR_N] || vars_h[VAR_N] || |
268 |
2/4✓ Branch 0 taken 19846 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 19846 times.
✗ Branch 3 not taken.
|
19846 | vars_w[VAR_T] || vars_h[VAR_T] || |
269 | #if FF_API_FRAME_PKT | ||
270 |
2/4✓ Branch 0 taken 19846 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 19846 times.
✗ Branch 3 not taken.
|
19846 | vars_w[VAR_POS] || vars_h[VAR_POS] || |
271 | #endif | ||
272 |
2/4✓ Branch 0 taken 19846 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 19846 times.
✗ Branch 3 not taken.
|
19846 | vars_w[VAR_S2R_MAIN_N] || vars_h[VAR_S2R_MAIN_N] || |
273 |
2/4✓ Branch 0 taken 19846 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 19846 times.
✗ Branch 3 not taken.
|
19846 | vars_w[VAR_S2R_MAIN_T] || vars_h[VAR_S2R_MAIN_T] || |
274 |
2/4✓ Branch 0 taken 19846 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 19846 times.
|
19846 | vars_w[VAR_S2R_MAIN_POS] || vars_h[VAR_S2R_MAIN_POS]) ) { |
275 | ✗ | av_log(ctx, AV_LOG_ERROR, "Expressions with frame variables 'n', 't', 'pos' are not valid in init eval_mode.\n"); | |
276 | ✗ | return AVERROR(EINVAL); | |
277 | } | ||
278 | |||
279 | 19846 | return 0; | |
280 | } | ||
281 | |||
282 | 19846 | static int scale_parse_expr(AVFilterContext *ctx, char *str_expr, AVExpr **pexpr_ptr, const char *var, const char *args) | |
283 | { | ||
284 | 19846 | ScaleContext *scale = ctx->priv; | |
285 | 19846 | int ret, is_inited = 0; | |
286 | 19846 | char *old_str_expr = NULL; | |
287 | 19846 | AVExpr *old_pexpr = NULL; | |
288 | |||
289 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 19846 times.
|
19846 | if (str_expr) { |
290 | ✗ | old_str_expr = av_strdup(str_expr); | |
291 | ✗ | if (!old_str_expr) | |
292 | ✗ | return AVERROR(ENOMEM); | |
293 | ✗ | av_opt_set(scale, var, args, 0); | |
294 | } | ||
295 | |||
296 |
2/2✓ Branch 0 taken 34 times.
✓ Branch 1 taken 19812 times.
|
19846 | if (*pexpr_ptr) { |
297 | 34 | old_pexpr = *pexpr_ptr; | |
298 | 34 | *pexpr_ptr = NULL; | |
299 | 34 | is_inited = 1; | |
300 | } | ||
301 | |||
302 | 19846 | ret = av_expr_parse(pexpr_ptr, args, var_names, | |
303 | NULL, NULL, NULL, NULL, 0, ctx); | ||
304 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 19846 times.
|
19846 | if (ret < 0) { |
305 | ✗ | av_log(ctx, AV_LOG_ERROR, "Cannot parse expression for %s: '%s'\n", var, args); | |
306 | ✗ | goto revert; | |
307 | } | ||
308 | |||
309 | 19846 | ret = check_exprs(ctx); | |
310 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 19846 times.
|
19846 | if (ret < 0) |
311 | ✗ | goto revert; | |
312 | |||
313 |
3/4✓ Branch 0 taken 34 times.
✓ Branch 1 taken 19812 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 34 times.
|
19846 | if (is_inited && (ret = config_props(ctx->outputs[0])) < 0) |
314 | ✗ | goto revert; | |
315 | |||
316 | 19846 | av_expr_free(old_pexpr); | |
317 | 19846 | old_pexpr = NULL; | |
318 | 19846 | av_freep(&old_str_expr); | |
319 | |||
320 | 19846 | return 0; | |
321 | |||
322 | ✗ | revert: | |
323 | ✗ | av_expr_free(*pexpr_ptr); | |
324 | ✗ | *pexpr_ptr = NULL; | |
325 | ✗ | if (old_str_expr) { | |
326 | ✗ | av_opt_set(scale, var, old_str_expr, 0); | |
327 | ✗ | av_free(old_str_expr); | |
328 | } | ||
329 | ✗ | if (old_pexpr) | |
330 | ✗ | *pexpr_ptr = old_pexpr; | |
331 | |||
332 | ✗ | return ret; | |
333 | } | ||
334 | |||
335 | 9906 | static av_cold int preinit(AVFilterContext *ctx) | |
336 | { | ||
337 | 9906 | ScaleContext *scale = ctx->priv; | |
338 | |||
339 | 9906 | scale->sws = sws_alloc_context(); | |
340 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 9906 times.
|
9906 | if (!scale->sws) |
341 | ✗ | return AVERROR(ENOMEM); | |
342 | |||
343 | // set threads=0, so we can later check whether the user modified it | ||
344 | 9906 | scale->sws->threads = 0; | |
345 | |||
346 | 9906 | ff_framesync_preinit(&scale->fs); | |
347 | |||
348 | 9906 | return 0; | |
349 | } | ||
350 | |||
351 | static int do_scale(FFFrameSync *fs); | ||
352 | |||
353 | 9906 | static av_cold int init(AVFilterContext *ctx) | |
354 | { | ||
355 | 9906 | ScaleContext *scale = ctx->priv; | |
356 | int ret; | ||
357 | |||
358 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 9906 times.
|
9906 | if (IS_SCALE2REF(ctx)) |
359 | ✗ | av_log(ctx, AV_LOG_WARNING, "scale2ref is deprecated, use scale=rw:rh instead\n"); | |
360 | |||
361 |
1/6✗ Branch 0 not taken.
✓ Branch 1 taken 9906 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
|
9906 | if (scale->size_str && (scale->w_expr || scale->h_expr)) { |
362 | ✗ | av_log(ctx, AV_LOG_ERROR, | |
363 | "Size and width/height expressions cannot be set at the same time.\n"); | ||
364 | ✗ | return AVERROR(EINVAL); | |
365 | } | ||
366 | |||
367 |
3/4✓ Branch 0 taken 1509 times.
✓ Branch 1 taken 8397 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1509 times.
|
9906 | if (scale->w_expr && !scale->h_expr) |
368 | ✗ | FFSWAP(char *, scale->w_expr, scale->size_str); | |
369 | |||
370 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 9906 times.
|
9906 | if (scale->size_str) { |
371 | char buf[32]; | ||
372 | ✗ | if ((ret = av_parse_video_size(&scale->w, &scale->h, scale->size_str)) < 0) { | |
373 | ✗ | av_log(ctx, AV_LOG_ERROR, | |
374 | "Invalid size '%s'\n", scale->size_str); | ||
375 | ✗ | return ret; | |
376 | } | ||
377 | ✗ | snprintf(buf, sizeof(buf)-1, "%d", scale->w); | |
378 | ✗ | av_opt_set(scale, "w", buf, 0); | |
379 | ✗ | snprintf(buf, sizeof(buf)-1, "%d", scale->h); | |
380 | ✗ | av_opt_set(scale, "h", buf, 0); | |
381 | } | ||
382 |
2/2✓ Branch 0 taken 8397 times.
✓ Branch 1 taken 1509 times.
|
9906 | if (!scale->w_expr) |
383 | 8397 | av_opt_set(scale, "w", "iw", 0); | |
384 |
2/2✓ Branch 0 taken 8397 times.
✓ Branch 1 taken 1509 times.
|
9906 | if (!scale->h_expr) |
385 | 8397 | av_opt_set(scale, "h", "ih", 0); | |
386 | |||
387 | 9906 | ret = scale_parse_expr(ctx, NULL, &scale->w_pexpr, "width", scale->w_expr); | |
388 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 9906 times.
|
9906 | if (ret < 0) |
389 | ✗ | return ret; | |
390 | |||
391 | 9906 | ret = scale_parse_expr(ctx, NULL, &scale->h_pexpr, "height", scale->h_expr); | |
392 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 9906 times.
|
9906 | if (ret < 0) |
393 | ✗ | return ret; | |
394 | |||
395 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 9906 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
9906 | if (scale->in_primaries != -1 && !sws_test_primaries(scale->in_primaries, 0)) { |
396 | ✗ | av_log(ctx, AV_LOG_ERROR, "Unsupported input primaries '%s'\n", | |
397 | ✗ | av_color_primaries_name(scale->in_primaries)); | |
398 | ✗ | return AVERROR(EINVAL); | |
399 | } | ||
400 | |||
401 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 9906 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
9906 | if (scale->out_primaries != -1 && !sws_test_primaries(scale->out_primaries, 1)) { |
402 | ✗ | av_log(ctx, AV_LOG_ERROR, "Unsupported output primaries '%s'\n", | |
403 | ✗ | av_color_primaries_name(scale->out_primaries)); | |
404 | ✗ | return AVERROR(EINVAL); | |
405 | } | ||
406 | |||
407 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 9906 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
9906 | if (scale->in_transfer != -1 && !sws_test_transfer(scale->in_transfer, 0)) { |
408 | ✗ | av_log(ctx, AV_LOG_ERROR, "Unsupported input transfer '%s'\n", | |
409 | ✗ | av_color_transfer_name(scale->in_transfer)); | |
410 | ✗ | return AVERROR(EINVAL); | |
411 | } | ||
412 | |||
413 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 9906 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
9906 | if (scale->out_transfer != -1 && !sws_test_transfer(scale->out_transfer, 1)) { |
414 | ✗ | av_log(ctx, AV_LOG_ERROR, "Unsupported output transfer '%s'\n", | |
415 | ✗ | av_color_transfer_name(scale->out_transfer)); | |
416 | ✗ | return AVERROR(EINVAL); | |
417 | } | ||
418 | |||
419 |
3/4✓ Branch 0 taken 4 times.
✓ Branch 1 taken 9902 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
|
9906 | if (scale->in_color_matrix != -1 && !sws_test_colorspace(scale->in_color_matrix, 0)) { |
420 | ✗ | av_log(ctx, AV_LOG_ERROR, "Unsupported input color matrix '%s'\n", | |
421 | ✗ | av_color_space_name(scale->in_color_matrix)); | |
422 | ✗ | return AVERROR(EINVAL); | |
423 | } | ||
424 | |||
425 |
2/4✓ Branch 0 taken 9906 times.
✗ Branch 1 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 9906 times.
|
9906 | if (scale->out_color_matrix != -1 && !sws_test_colorspace(scale->out_color_matrix, 1)) { |
426 | ✗ | av_log(ctx, AV_LOG_ERROR, "Unsupported output color matrix '%s'\n", | |
427 | ✗ | av_color_space_name(scale->out_color_matrix)); | |
428 | ✗ | return AVERROR(EINVAL); | |
429 | } | ||
430 | |||
431 | 9906 | av_log(ctx, AV_LOG_VERBOSE, "w:%s h:%s flags:'%s' interl:%d\n", | |
432 | 9906 | scale->w_expr, scale->h_expr, (char *)av_x_if_null(scale->flags_str, ""), scale->interlaced); | |
433 | |||
434 |
3/4✓ Branch 0 taken 9906 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1596 times.
✓ Branch 3 taken 8310 times.
|
9906 | if (scale->flags_str && *scale->flags_str) { |
435 | 1596 | ret = av_opt_set(scale->sws, "sws_flags", scale->flags_str, 0); | |
436 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1596 times.
|
1596 | if (ret < 0) |
437 | ✗ | return ret; | |
438 | } | ||
439 | |||
440 |
2/2✓ Branch 0 taken 19812 times.
✓ Branch 1 taken 9906 times.
|
29718 | for (int i = 0; i < FF_ARRAY_ELEMS(scale->param); i++) |
441 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 19812 times.
|
19812 | if (scale->param[i] != DBL_MAX) |
442 | ✗ | scale->sws->scaler_params[i] = scale->param[i]; | |
443 | |||
444 | 9906 | scale->sws->src_h_chr_pos = scale->in_h_chr_pos; | |
445 | 9906 | scale->sws->src_v_chr_pos = scale->in_v_chr_pos; | |
446 | 9906 | scale->sws->dst_h_chr_pos = scale->out_h_chr_pos; | |
447 | 9906 | scale->sws->dst_v_chr_pos = scale->out_v_chr_pos; | |
448 | |||
449 | // use generic thread-count if the user did not set it explicitly | ||
450 |
1/2✓ Branch 0 taken 9906 times.
✗ Branch 1 not taken.
|
9906 | if (!scale->sws->threads) |
451 | 9906 | scale->sws->threads = ff_filter_get_nb_threads(ctx); | |
452 | |||
453 |
3/4✓ Branch 0 taken 9906 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 9904 times.
|
9906 | if (!IS_SCALE2REF(ctx) && scale->uses_ref) { |
454 | 2 | AVFilterPad pad = { | |
455 | .name = "ref", | ||
456 | .type = AVMEDIA_TYPE_VIDEO, | ||
457 | }; | ||
458 | 2 | ret = ff_append_inpad(ctx, &pad); | |
459 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
2 | if (ret < 0) |
460 | ✗ | return ret; | |
461 | } | ||
462 | |||
463 | 9906 | return 0; | |
464 | } | ||
465 | |||
466 | 9906 | static av_cold void uninit(AVFilterContext *ctx) | |
467 | { | ||
468 | 9906 | ScaleContext *scale = ctx->priv; | |
469 | 9906 | av_expr_free(scale->w_pexpr); | |
470 | 9906 | av_expr_free(scale->h_pexpr); | |
471 | 9906 | scale->w_pexpr = scale->h_pexpr = NULL; | |
472 | 9906 | ff_framesync_uninit(&scale->fs); | |
473 | 9906 | sws_free_context(&scale->sws); | |
474 | 9906 | } | |
475 | |||
476 | 5826 | static int query_formats(const AVFilterContext *ctx, | |
477 | AVFilterFormatsConfig **cfg_in, | ||
478 | AVFilterFormatsConfig **cfg_out) | ||
479 | { | ||
480 | 5826 | const ScaleContext *scale = ctx->priv; | |
481 | AVFilterFormats *formats; | ||
482 | const AVPixFmtDescriptor *desc; | ||
483 | enum AVPixelFormat pix_fmt; | ||
484 | int ret; | ||
485 | |||
486 | 5826 | desc = NULL; | |
487 | 5826 | formats = NULL; | |
488 |
2/2✓ Branch 1 taken 1468152 times.
✓ Branch 2 taken 5826 times.
|
1473978 | while ((desc = av_pix_fmt_desc_next(desc))) { |
489 | 1468152 | pix_fmt = av_pix_fmt_desc_get_id(desc); | |
490 |
2/2✓ Branch 1 taken 1264242 times.
✓ Branch 2 taken 203910 times.
|
1468152 | if (sws_test_format(pix_fmt, 0)) { |
491 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1264242 times.
|
1264242 | if ((ret = ff_add_format(&formats, pix_fmt)) < 0) |
492 | ✗ | return ret; | |
493 | } | ||
494 | } | ||
495 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 5826 times.
|
5826 | if ((ret = ff_formats_ref(formats, &cfg_in[0]->formats)) < 0) |
496 | ✗ | return ret; | |
497 | |||
498 | 5826 | desc = NULL; | |
499 | 5826 | formats = NULL; | |
500 |
2/2✓ Branch 1 taken 1468152 times.
✓ Branch 2 taken 5826 times.
|
1473978 | while ((desc = av_pix_fmt_desc_next(desc))) { |
501 | 1468152 | pix_fmt = av_pix_fmt_desc_get_id(desc); | |
502 |
4/4✓ Branch 1 taken 337908 times.
✓ Branch 2 taken 1130244 times.
✓ Branch 3 taken 5826 times.
✓ Branch 4 taken 332082 times.
|
1468152 | if (sws_test_format(pix_fmt, 1) || pix_fmt == AV_PIX_FMT_PAL8) { |
503 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1136070 times.
|
1136070 | if ((ret = ff_add_format(&formats, pix_fmt)) < 0) |
504 | ✗ | return ret; | |
505 | } | ||
506 | } | ||
507 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 5826 times.
|
5826 | if ((ret = ff_formats_ref(formats, &cfg_out[0]->formats)) < 0) |
508 | ✗ | return ret; | |
509 | |||
510 | /* accept all supported inputs, even if user overrides their properties */ | ||
511 | 5826 | formats = ff_all_color_spaces(); | |
512 |
2/2✓ Branch 0 taken 99042 times.
✓ Branch 1 taken 5826 times.
|
104868 | for (int i = 0; i < formats->nb_formats; i++) { |
513 |
2/2✓ Branch 1 taken 52434 times.
✓ Branch 2 taken 46608 times.
|
99042 | if (!sws_test_colorspace(formats->formats[i], 0)) { |
514 |
2/2✓ Branch 0 taken 215562 times.
✓ Branch 1 taken 52434 times.
|
267996 | for (int j = i--; j + 1 < formats->nb_formats; j++) |
515 | 215562 | formats->formats[j] = formats->formats[j + 1]; | |
516 | 52434 | formats->nb_formats--; | |
517 | } | ||
518 | } | ||
519 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 5826 times.
|
5826 | if ((ret = ff_formats_ref(formats, &cfg_in[0]->color_spaces)) < 0) |
520 | ✗ | return ret; | |
521 | |||
522 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 5826 times.
|
5826 | if ((ret = ff_formats_ref(ff_all_color_ranges(), |
523 | 5826 | &cfg_in[0]->color_ranges)) < 0) | |
524 | ✗ | return ret; | |
525 | |||
526 | /* propagate output properties if overridden */ | ||
527 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 5824 times.
|
5826 | if (scale->out_color_matrix != AVCOL_SPC_UNSPECIFIED) { |
528 | 2 | formats = ff_make_formats_list_singleton(scale->out_color_matrix); | |
529 | } else { | ||
530 | 5824 | formats = ff_all_color_spaces(); | |
531 |
2/2✓ Branch 0 taken 99008 times.
✓ Branch 1 taken 5824 times.
|
104832 | for (int i = 0; i < formats->nb_formats; i++) { |
532 |
2/2✓ Branch 1 taken 52416 times.
✓ Branch 2 taken 46592 times.
|
99008 | if (!sws_test_colorspace(formats->formats[i], 1)) { |
533 |
2/2✓ Branch 0 taken 215488 times.
✓ Branch 1 taken 52416 times.
|
267904 | for (int j = i--; j + 1 < formats->nb_formats; j++) |
534 | 215488 | formats->formats[j] = formats->formats[j + 1]; | |
535 | 52416 | formats->nb_formats--; | |
536 | } | ||
537 | } | ||
538 | } | ||
539 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 5826 times.
|
5826 | if ((ret = ff_formats_ref(formats, &cfg_out[0]->color_spaces)) < 0) |
540 | ✗ | return ret; | |
541 | |||
542 | 11652 | formats = scale->out_range != AVCOL_RANGE_UNSPECIFIED | |
543 | 2 | ? ff_make_formats_list_singleton(scale->out_range) | |
544 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 5824 times.
|
5826 | : ff_all_color_ranges(); |
545 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 5826 times.
|
5826 | if ((ret = ff_formats_ref(formats, &cfg_out[0]->color_ranges)) < 0) |
546 | ✗ | return ret; | |
547 | |||
548 | 5826 | return 0; | |
549 | } | ||
550 | |||
551 | 5832 | static int scale_eval_dimensions(AVFilterContext *ctx) | |
552 | { | ||
553 | 5832 | ScaleContext *scale = ctx->priv; | |
554 | 5832 | const char scale2ref = IS_SCALE2REF(ctx); | |
555 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 5832 times.
|
5832 | const AVFilterLink *inlink = scale2ref ? ctx->inputs[1] : ctx->inputs[0]; |
556 | 5832 | const AVFilterLink *outlink = ctx->outputs[0]; | |
557 | 5832 | const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format); | |
558 | 5832 | const AVPixFmtDescriptor *out_desc = av_pix_fmt_desc_get(outlink->format); | |
559 | char *expr; | ||
560 | int eval_w, eval_h; | ||
561 | int ret; | ||
562 | double res; | ||
563 | const AVPixFmtDescriptor *main_desc; | ||
564 | const AVFilterLink *main_link; | ||
565 | |||
566 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 5832 times.
|
5832 | if (scale2ref) { |
567 | ✗ | main_link = ctx->inputs[0]; | |
568 | ✗ | main_desc = av_pix_fmt_desc_get(main_link->format); | |
569 | } | ||
570 | |||
571 | 5832 | scale->var_values[VAR_IN_W] = scale->var_values[VAR_IW] = inlink->w; | |
572 | 5832 | scale->var_values[VAR_IN_H] = scale->var_values[VAR_IH] = inlink->h; | |
573 | 5832 | scale->var_values[VAR_OUT_W] = scale->var_values[VAR_OW] = NAN; | |
574 | 5832 | scale->var_values[VAR_OUT_H] = scale->var_values[VAR_OH] = NAN; | |
575 | 5832 | scale->var_values[VAR_A] = (double) inlink->w / inlink->h; | |
576 | 11664 | scale->var_values[VAR_SAR] = inlink->sample_aspect_ratio.num ? | |
577 |
2/2✓ Branch 0 taken 1848 times.
✓ Branch 1 taken 3984 times.
|
5832 | (double) inlink->sample_aspect_ratio.num / inlink->sample_aspect_ratio.den : 1; |
578 | 5832 | scale->var_values[VAR_DAR] = scale->var_values[VAR_A] * scale->var_values[VAR_SAR]; | |
579 | 5832 | scale->var_values[VAR_HSUB] = 1 << desc->log2_chroma_w; | |
580 | 5832 | scale->var_values[VAR_VSUB] = 1 << desc->log2_chroma_h; | |
581 | 5832 | scale->var_values[VAR_OHSUB] = 1 << out_desc->log2_chroma_w; | |
582 | 5832 | scale->var_values[VAR_OVSUB] = 1 << out_desc->log2_chroma_h; | |
583 | |||
584 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 5832 times.
|
5832 | if (scale2ref) { |
585 | ✗ | scale->var_values[VAR_S2R_MAIN_W] = main_link->w; | |
586 | ✗ | scale->var_values[VAR_S2R_MAIN_H] = main_link->h; | |
587 | ✗ | scale->var_values[VAR_S2R_MAIN_A] = (double) main_link->w / main_link->h; | |
588 | ✗ | scale->var_values[VAR_S2R_MAIN_SAR] = main_link->sample_aspect_ratio.num ? | |
589 | ✗ | (double) main_link->sample_aspect_ratio.num / main_link->sample_aspect_ratio.den : 1; | |
590 | ✗ | scale->var_values[VAR_S2R_MAIN_DAR] = scale->var_values[VAR_S2R_MDAR] = | |
591 | ✗ | scale->var_values[VAR_S2R_MAIN_A] * scale->var_values[VAR_S2R_MAIN_SAR]; | |
592 | ✗ | scale->var_values[VAR_S2R_MAIN_HSUB] = 1 << main_desc->log2_chroma_w; | |
593 | ✗ | scale->var_values[VAR_S2R_MAIN_VSUB] = 1 << main_desc->log2_chroma_h; | |
594 | } | ||
595 | |||
596 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 5831 times.
|
5832 | if (scale->uses_ref) { |
597 | 1 | const AVFilterLink *reflink = ctx->inputs[1]; | |
598 | 1 | const AVPixFmtDescriptor *ref_desc = av_pix_fmt_desc_get(reflink->format); | |
599 | 1 | scale->var_values[VAR_REF_W] = scale->var_values[VAR_RW] = reflink->w; | |
600 | 1 | scale->var_values[VAR_REF_H] = scale->var_values[VAR_RH] = reflink->h; | |
601 | 1 | scale->var_values[VAR_REF_A] = (double) reflink->w / reflink->h; | |
602 | 2 | scale->var_values[VAR_REF_SAR] = reflink->sample_aspect_ratio.num ? | |
603 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | (double) reflink->sample_aspect_ratio.num / reflink->sample_aspect_ratio.den : 1; |
604 | 1 | scale->var_values[VAR_REF_DAR] = scale->var_values[VAR_RDAR] = | |
605 | 1 | scale->var_values[VAR_REF_A] * scale->var_values[VAR_REF_SAR]; | |
606 | 1 | scale->var_values[VAR_REF_HSUB] = 1 << ref_desc->log2_chroma_w; | |
607 | 1 | scale->var_values[VAR_REF_VSUB] = 1 << ref_desc->log2_chroma_h; | |
608 | } | ||
609 | |||
610 | 5832 | res = av_expr_eval(scale->w_pexpr, scale->var_values, NULL); | |
611 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 5832 times.
|
5832 | eval_w = scale->var_values[VAR_OUT_W] = scale->var_values[VAR_OW] = (int) res == 0 ? inlink->w : (int) res; |
612 | |||
613 | 5832 | res = av_expr_eval(scale->h_pexpr, scale->var_values, NULL); | |
614 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 5832 times.
|
5832 | if (isnan(res)) { |
615 | ✗ | expr = scale->h_expr; | |
616 | ✗ | ret = AVERROR(EINVAL); | |
617 | ✗ | goto fail; | |
618 | } | ||
619 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 5832 times.
|
5832 | eval_h = scale->var_values[VAR_OUT_H] = scale->var_values[VAR_OH] = (int) res == 0 ? inlink->h : (int) res; |
620 | |||
621 | 5832 | res = av_expr_eval(scale->w_pexpr, scale->var_values, NULL); | |
622 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 5832 times.
|
5832 | if (isnan(res)) { |
623 | ✗ | expr = scale->w_expr; | |
624 | ✗ | ret = AVERROR(EINVAL); | |
625 | ✗ | goto fail; | |
626 | } | ||
627 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 5832 times.
|
5832 | eval_w = scale->var_values[VAR_OUT_W] = scale->var_values[VAR_OW] = (int) res == 0 ? inlink->w : (int) res; |
628 | |||
629 | 5832 | scale->w = eval_w; | |
630 | 5832 | scale->h = eval_h; | |
631 | |||
632 | 5832 | return 0; | |
633 | |||
634 | ✗ | fail: | |
635 | ✗ | av_log(ctx, AV_LOG_ERROR, | |
636 | "Error when evaluating the expression '%s'.\n", expr); | ||
637 | ✗ | return ret; | |
638 | } | ||
639 | |||
640 | 5832 | static int config_props(AVFilterLink *outlink) | |
641 | { | ||
642 | 5832 | AVFilterContext *ctx = outlink->src; | |
643 | 5832 | AVFilterLink *inlink0 = outlink->src->inputs[0]; | |
644 | 11664 | AVFilterLink *inlink = IS_SCALE2REF(ctx) ? | |
645 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 5832 times.
|
5832 | outlink->src->inputs[1] : |
646 | 5832 | outlink->src->inputs[0]; | |
647 | 5832 | ScaleContext *scale = ctx->priv; | |
648 | 5832 | uint8_t *flags_val = NULL; | |
649 | 5832 | double w_adj = 1.0; | |
650 | int ret; | ||
651 | |||
652 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 5832 times.
|
5832 | if ((ret = scale_eval_dimensions(ctx)) < 0) |
653 | ✗ | goto fail; | |
654 | |||
655 | 5832 | outlink->w = scale->w; | |
656 | 5832 | outlink->h = scale->h; | |
657 | |||
658 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 5832 times.
|
5832 | if (scale->reset_sar) |
659 | ✗ | w_adj = IS_SCALE2REF(ctx) ? scale->var_values[VAR_S2R_MAIN_SAR] : | |
660 | scale->var_values[VAR_SAR]; | ||
661 | |||
662 | 5832 | ret = ff_scale_adjust_dimensions(inlink, &outlink->w, &outlink->h, | |
663 | scale->force_original_aspect_ratio, | ||
664 | scale->force_divisible_by, w_adj); | ||
665 | |||
666 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 5832 times.
|
5832 | if (ret < 0) |
667 | ✗ | goto fail; | |
668 | |||
669 | if (outlink->w > INT_MAX || | ||
670 | outlink->h > INT_MAX || | ||
671 | (outlink->h * inlink->w) > INT_MAX || | ||
672 | (outlink->w * inlink->h) > INT_MAX) | ||
673 | av_log(ctx, AV_LOG_ERROR, "Rescaled value for width or height is too big.\n"); | ||
674 | |||
675 | /* TODO: make algorithm configurable */ | ||
676 | |||
677 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 5832 times.
|
5832 | if (scale->reset_sar) |
678 | ✗ | outlink->sample_aspect_ratio = (AVRational){1, 1}; | |
679 |
2/2✓ Branch 0 taken 1848 times.
✓ Branch 1 taken 3984 times.
|
5832 | else if (inlink0->sample_aspect_ratio.num){ |
680 | 1848 | outlink->sample_aspect_ratio = av_mul_q((AVRational){outlink->h * inlink0->w, outlink->w * inlink0->h}, inlink0->sample_aspect_ratio); | |
681 | } else | ||
682 | 3984 | outlink->sample_aspect_ratio = inlink0->sample_aspect_ratio; | |
683 | |||
684 | 5832 | av_opt_get(scale->sws, "sws_flags", 0, &flags_val); | |
685 | 17496 | av_log(ctx, AV_LOG_VERBOSE, "w:%d h:%d fmt:%s csp:%s range:%s sar:%d/%d -> w:%d h:%d fmt:%s csp:%s range:%s sar:%d/%d flags:%s\n", | |
686 | 5832 | inlink ->w, inlink ->h, av_get_pix_fmt_name( inlink->format), | |
687 | av_color_space_name(inlink->colorspace), av_color_range_name(inlink->color_range), | ||
688 | inlink->sample_aspect_ratio.num, inlink->sample_aspect_ratio.den, | ||
689 | 5832 | outlink->w, outlink->h, av_get_pix_fmt_name(outlink->format), | |
690 | av_color_space_name(outlink->colorspace), av_color_range_name(outlink->color_range), | ||
691 | outlink->sample_aspect_ratio.num, outlink->sample_aspect_ratio.den, | ||
692 | flags_val); | ||
693 | 5832 | av_freep(&flags_val); | |
694 | |||
695 |
4/4✓ Branch 0 taken 5388 times.
✓ Branch 1 taken 444 times.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 5378 times.
|
5832 | if (inlink->w != outlink->w || inlink->h != outlink->h) { |
696 | 454 | av_frame_side_data_remove_by_props(&outlink->side_data, &outlink->nb_side_data, | |
697 | AV_SIDE_DATA_PROP_SIZE_DEPENDENT); | ||
698 | } | ||
699 | |||
700 |
2/4✓ Branch 0 taken 5832 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 5832 times.
|
5832 | if (scale->in_primaries != scale->out_primaries || scale->in_transfer != scale->out_transfer) { |
701 | ✗ | av_frame_side_data_remove_by_props(&outlink->side_data, &outlink->nb_side_data, | |
702 | AV_SIDE_DATA_PROP_COLOR_DEPENDENT); | ||
703 | } | ||
704 | |||
705 |
1/2✓ Branch 0 taken 5832 times.
✗ Branch 1 not taken.
|
5832 | if (!IS_SCALE2REF(ctx)) { |
706 | 5832 | ff_framesync_uninit(&scale->fs); | |
707 | 5832 | ret = ff_framesync_init(&scale->fs, ctx, ctx->nb_inputs); | |
708 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 5832 times.
|
5832 | if (ret < 0) |
709 | ✗ | return ret; | |
710 | 5832 | scale->fs.on_event = do_scale; | |
711 | 5832 | scale->fs.in[0].time_base = ctx->inputs[0]->time_base; | |
712 | 5832 | scale->fs.in[0].sync = 1; | |
713 | 5832 | scale->fs.in[0].before = EXT_STOP; | |
714 | 5832 | scale->fs.in[0].after = EXT_STOP; | |
715 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 5831 times.
|
5832 | if (scale->uses_ref) { |
716 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | av_assert0(ctx->nb_inputs == 2); |
717 | 1 | scale->fs.in[1].time_base = ctx->inputs[1]->time_base; | |
718 | 1 | scale->fs.in[1].sync = 0; | |
719 | 1 | scale->fs.in[1].before = EXT_NULL; | |
720 | 1 | scale->fs.in[1].after = EXT_INFINITY; | |
721 | } | ||
722 | |||
723 | 5832 | ret = ff_framesync_configure(&scale->fs); | |
724 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 5832 times.
|
5832 | if (ret < 0) |
725 | ✗ | return ret; | |
726 | } | ||
727 | |||
728 | 5832 | return 0; | |
729 | |||
730 | ✗ | fail: | |
731 | ✗ | return ret; | |
732 | } | ||
733 | |||
734 | ✗ | static int config_props_ref(AVFilterLink *outlink) | |
735 | { | ||
736 | ✗ | AVFilterLink *inlink = outlink->src->inputs[1]; | |
737 | ✗ | FilterLink *il = ff_filter_link(inlink); | |
738 | ✗ | FilterLink *ol = ff_filter_link(outlink); | |
739 | |||
740 | ✗ | outlink->w = inlink->w; | |
741 | ✗ | outlink->h = inlink->h; | |
742 | ✗ | outlink->sample_aspect_ratio = inlink->sample_aspect_ratio; | |
743 | ✗ | outlink->time_base = inlink->time_base; | |
744 | ✗ | ol->frame_rate = il->frame_rate; | |
745 | ✗ | outlink->colorspace = inlink->colorspace; | |
746 | ✗ | outlink->color_range = inlink->color_range; | |
747 | |||
748 | ✗ | return 0; | |
749 | } | ||
750 | |||
751 | ✗ | static int request_frame(AVFilterLink *outlink) | |
752 | { | ||
753 | ✗ | return ff_request_frame(outlink->src->inputs[0]); | |
754 | } | ||
755 | |||
756 | ✗ | static int request_frame_ref(AVFilterLink *outlink) | |
757 | { | ||
758 | ✗ | return ff_request_frame(outlink->src->inputs[1]); | |
759 | } | ||
760 | |||
761 | /* Takes over ownership of *frame_in, passes ownership of *frame_out to caller */ | ||
762 | 88985 | static int scale_frame(AVFilterLink *link, AVFrame **frame_in, | |
763 | AVFrame **frame_out) | ||
764 | { | ||
765 | 88985 | FilterLink *inl = ff_filter_link(link); | |
766 | 88985 | AVFilterContext *ctx = link->dst; | |
767 | 88985 | ScaleContext *scale = ctx->priv; | |
768 | 88985 | AVFilterLink *outlink = ctx->outputs[0]; | |
769 | 88985 | AVFrame *out, *in = *frame_in; | |
770 | 88985 | const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(link->format); | |
771 | char buf[32]; | ||
772 | int ret, flags_orig, frame_changed; | ||
773 | |||
774 | 88985 | *frame_in = NULL; | |
775 | |||
776 | 266954 | frame_changed = in->width != link->w || | |
777 |
1/2✓ Branch 0 taken 88984 times.
✗ Branch 1 not taken.
|
88984 | in->height != link->h || |
778 |
1/2✓ Branch 0 taken 88984 times.
✗ Branch 1 not taken.
|
88984 | in->format != link->format || |
779 |
1/2✓ Branch 0 taken 88984 times.
✗ Branch 1 not taken.
|
88984 | in->sample_aspect_ratio.den != link->sample_aspect_ratio.den || |
780 |
1/2✓ Branch 0 taken 88984 times.
✗ Branch 1 not taken.
|
88984 | in->sample_aspect_ratio.num != link->sample_aspect_ratio.num || |
781 |
4/4✓ Branch 0 taken 88984 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 88969 times.
✓ Branch 3 taken 15 times.
|
266938 | in->colorspace != link->colorspace || |
782 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 88968 times.
|
88969 | in->color_range != link->color_range; |
783 | |||
784 |
3/4✓ Branch 0 taken 88985 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 17 times.
✓ Branch 3 taken 88968 times.
|
88985 | if (scale->eval_mode == EVAL_MODE_FRAME || frame_changed) { |
785 | 17 | unsigned vars_w[VARS_NB] = { 0 }, vars_h[VARS_NB] = { 0 }; | |
786 | |||
787 | 17 | av_expr_count_vars(scale->w_pexpr, vars_w, VARS_NB); | |
788 | 17 | av_expr_count_vars(scale->h_pexpr, vars_h, VARS_NB); | |
789 | |||
790 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
17 | if (scale->eval_mode == EVAL_MODE_FRAME && |
791 | ✗ | !frame_changed && | |
792 | ✗ | !IS_SCALE2REF(ctx) && | |
793 | ✗ | !(vars_w[VAR_N] || vars_w[VAR_T] | |
794 | #if FF_API_FRAME_PKT | ||
795 | ✗ | || vars_w[VAR_POS] | |
796 | #endif | ||
797 | ✗ | ) && | |
798 | ✗ | !(vars_h[VAR_N] || vars_h[VAR_T] | |
799 | #if FF_API_FRAME_PKT | ||
800 | ✗ | || vars_h[VAR_POS] | |
801 | #endif | ||
802 | ✗ | ) && | |
803 | ✗ | scale->w && scale->h) | |
804 | ✗ | goto scale; | |
805 | |||
806 |
1/2✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
|
17 | if (scale->eval_mode == EVAL_MODE_INIT) { |
807 | 17 | snprintf(buf, sizeof(buf) - 1, "%d", scale->w); | |
808 | 17 | av_opt_set(scale, "w", buf, 0); | |
809 | 17 | snprintf(buf, sizeof(buf) - 1, "%d", scale->h); | |
810 | 17 | av_opt_set(scale, "h", buf, 0); | |
811 | |||
812 | 17 | ret = scale_parse_expr(ctx, NULL, &scale->w_pexpr, "width", scale->w_expr); | |
813 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
|
17 | if (ret < 0) |
814 | ✗ | goto err; | |
815 | |||
816 | 17 | ret = scale_parse_expr(ctx, NULL, &scale->h_pexpr, "height", scale->h_expr); | |
817 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
|
17 | if (ret < 0) |
818 | ✗ | goto err; | |
819 | } | ||
820 | |||
821 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
|
17 | if (IS_SCALE2REF(ctx)) { |
822 | ✗ | scale->var_values[VAR_S2R_MAIN_N] = inl->frame_count_out; | |
823 | ✗ | scale->var_values[VAR_S2R_MAIN_T] = TS2T(in->pts, link->time_base); | |
824 | #if FF_API_FRAME_PKT | ||
825 | FF_DISABLE_DEPRECATION_WARNINGS | ||
826 | ✗ | scale->var_values[VAR_S2R_MAIN_POS] = in->pkt_pos == -1 ? NAN : in->pkt_pos; | |
827 | FF_ENABLE_DEPRECATION_WARNINGS | ||
828 | #endif | ||
829 | } else { | ||
830 | 17 | scale->var_values[VAR_N] = inl->frame_count_out; | |
831 |
1/2✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
|
17 | scale->var_values[VAR_T] = TS2T(in->pts, link->time_base); |
832 | #if FF_API_FRAME_PKT | ||
833 | FF_DISABLE_DEPRECATION_WARNINGS | ||
834 |
2/2✓ Branch 0 taken 14 times.
✓ Branch 1 taken 3 times.
|
17 | scale->var_values[VAR_POS] = in->pkt_pos == -1 ? NAN : in->pkt_pos; |
835 | FF_ENABLE_DEPRECATION_WARNINGS | ||
836 | #endif | ||
837 | } | ||
838 | |||
839 | 17 | link->dst->inputs[0]->format = in->format; | |
840 | 17 | link->dst->inputs[0]->w = in->width; | |
841 | 17 | link->dst->inputs[0]->h = in->height; | |
842 | 17 | link->dst->inputs[0]->colorspace = in->colorspace; | |
843 | 17 | link->dst->inputs[0]->color_range = in->color_range; | |
844 | |||
845 | 17 | link->dst->inputs[0]->sample_aspect_ratio.den = in->sample_aspect_ratio.den; | |
846 | 17 | link->dst->inputs[0]->sample_aspect_ratio.num = in->sample_aspect_ratio.num; | |
847 | |||
848 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 17 times.
|
17 | if ((ret = config_props(outlink)) < 0) |
849 | ✗ | goto err; | |
850 | } | ||
851 | |||
852 | 88968 | scale: | |
853 | 88985 | scale->hsub = desc->log2_chroma_w; | |
854 | 88985 | scale->vsub = desc->log2_chroma_h; | |
855 | |||
856 | 88985 | out = ff_get_video_buffer(outlink, outlink->w, outlink->h); | |
857 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 88985 times.
|
88985 | if (!out) { |
858 | ✗ | ret = AVERROR(ENOMEM); | |
859 | ✗ | goto err; | |
860 | } | ||
861 | |||
862 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 88983 times.
|
88985 | if (scale->in_color_matrix != -1) |
863 | 2 | in->colorspace = scale->in_color_matrix; | |
864 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 88985 times.
|
88985 | if (scale->in_primaries != -1) |
865 | ✗ | in->color_primaries = scale->in_primaries; | |
866 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 88985 times.
|
88985 | if (scale->in_transfer != -1) |
867 | ✗ | in->color_trc = scale->in_transfer; | |
868 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 88983 times.
|
88985 | if (scale->in_range != AVCOL_RANGE_UNSPECIFIED) |
869 | 2 | in->color_range = scale->in_range; | |
870 | 88985 | in->chroma_location = scale->in_chroma_loc; | |
871 | |||
872 | 88985 | flags_orig = in->flags; | |
873 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 88985 times.
|
88985 | if (scale->interlaced > 0) |
874 | ✗ | in->flags |= AV_FRAME_FLAG_INTERLACED; | |
875 |
1/2✓ Branch 0 taken 88985 times.
✗ Branch 1 not taken.
|
88985 | else if (!scale->interlaced) |
876 | 88985 | in->flags &= ~AV_FRAME_FLAG_INTERLACED; | |
877 | |||
878 | 88985 | av_frame_copy_props(out, in); | |
879 | 88985 | out->width = outlink->w; | |
880 | 88985 | out->height = outlink->h; | |
881 | 88985 | out->color_range = outlink->color_range; | |
882 | 88985 | out->colorspace = outlink->colorspace; | |
883 |
2/2✓ Branch 0 taken 25 times.
✓ Branch 1 taken 88960 times.
|
88985 | if (scale->out_chroma_loc != AVCHROMA_LOC_UNSPECIFIED) |
884 | 25 | out->chroma_location = scale->out_chroma_loc; | |
885 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 88985 times.
|
88985 | if (scale->out_primaries != -1) |
886 | ✗ | out->color_primaries = scale->out_primaries; | |
887 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 88985 times.
|
88985 | if (scale->out_transfer != -1) |
888 | ✗ | out->color_trc = scale->out_transfer; | |
889 | |||
890 |
4/4✓ Branch 0 taken 83085 times.
✓ Branch 1 taken 5900 times.
✓ Branch 2 taken 13 times.
✓ Branch 3 taken 83072 times.
|
88985 | if (out->width != in->width || out->height != in->height) { |
891 | 5913 | av_frame_side_data_remove_by_props(&out->side_data, &out->nb_side_data, | |
892 | AV_SIDE_DATA_PROP_SIZE_DEPENDENT); | ||
893 | } | ||
894 | |||
895 |
2/4✓ Branch 0 taken 88985 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 88985 times.
|
88985 | if (in->color_primaries != out->color_primaries || in->color_trc != out->color_trc) { |
896 | ✗ | av_frame_side_data_remove_by_props(&out->side_data, &out->nb_side_data, | |
897 | AV_SIDE_DATA_PROP_COLOR_DEPENDENT); | ||
898 | } | ||
899 | |||
900 | 88985 | av_reduce(&out->sample_aspect_ratio.num, &out->sample_aspect_ratio.den, | |
901 | 88985 | (int64_t)in->sample_aspect_ratio.num * outlink->h * link->w, | |
902 | 88985 | (int64_t)in->sample_aspect_ratio.den * outlink->w * link->h, | |
903 | INT_MAX); | ||
904 | |||
905 |
2/2✓ Branch 1 taken 4660 times.
✓ Branch 2 taken 84325 times.
|
88985 | if (sws_is_noop(out, in)) { |
906 | 4660 | av_frame_free(&out); | |
907 | 4660 | in->flags = flags_orig; | |
908 | 4660 | *frame_out = in; | |
909 | 4660 | return 0; | |
910 | } | ||
911 | |||
912 |
2/2✓ Branch 0 taken 581 times.
✓ Branch 1 taken 83744 times.
|
84325 | if (out->format == AV_PIX_FMT_PAL8) { |
913 | 581 | out->format = AV_PIX_FMT_BGR8; | |
914 | 581 | avpriv_set_systematic_pal2((uint32_t*) out->data[1], out->format); | |
915 | } | ||
916 | |||
917 | 84325 | ret = sws_scale_frame(scale->sws, out, in); | |
918 | 84325 | av_frame_free(&in); | |
919 | 84325 | out->flags = flags_orig; | |
920 | 84325 | out->format = outlink->format; /* undo PAL8 handling */ | |
921 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 84325 times.
|
84325 | if (ret < 0) |
922 | ✗ | av_frame_free(&out); | |
923 | 84325 | *frame_out = out; | |
924 | 84325 | return ret; | |
925 | |||
926 | ✗ | err: | |
927 | ✗ | av_frame_free(&in); | |
928 | ✗ | return ret; | |
929 | } | ||
930 | |||
931 | 88985 | static int do_scale(FFFrameSync *fs) | |
932 | { | ||
933 | 88985 | AVFilterContext *ctx = fs->parent; | |
934 | 88985 | ScaleContext *scale = ctx->priv; | |
935 | 88985 | AVFilterLink *outlink = ctx->outputs[0]; | |
936 | 88985 | AVFrame *out, *in = NULL, *ref = NULL; | |
937 | 88985 | int ret = 0, frame_changed; | |
938 | |||
939 | 88985 | ret = ff_framesync_get_frame(fs, 0, &in, 1); | |
940 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 88985 times.
|
88985 | if (ret < 0) |
941 | ✗ | goto err; | |
942 | |||
943 |
2/2✓ Branch 0 taken 5 times.
✓ Branch 1 taken 88980 times.
|
88985 | if (scale->uses_ref) { |
944 | 5 | ret = ff_framesync_get_frame(fs, 1, &ref, 0); | |
945 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
|
5 | if (ret < 0) |
946 | ✗ | goto err; | |
947 | } | ||
948 | |||
949 |
2/2✓ Branch 0 taken 5 times.
✓ Branch 1 taken 88980 times.
|
88985 | if (ref) { |
950 | 5 | AVFilterLink *reflink = ctx->inputs[1]; | |
951 | 5 | FilterLink *rl = ff_filter_link(reflink); | |
952 | |||
953 | 15 | frame_changed = ref->width != reflink->w || | |
954 |
1/2✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
|
5 | ref->height != reflink->h || |
955 |
1/2✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
|
5 | ref->format != reflink->format || |
956 |
1/2✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
|
5 | ref->sample_aspect_ratio.den != reflink->sample_aspect_ratio.den || |
957 |
1/2✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
|
5 | ref->sample_aspect_ratio.num != reflink->sample_aspect_ratio.num || |
958 |
2/4✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
|
15 | ref->colorspace != reflink->colorspace || |
959 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
|
5 | ref->color_range != reflink->color_range; |
960 | |||
961 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
|
5 | if (frame_changed) { |
962 | ✗ | reflink->format = ref->format; | |
963 | ✗ | reflink->w = ref->width; | |
964 | ✗ | reflink->h = ref->height; | |
965 | ✗ | reflink->sample_aspect_ratio.num = ref->sample_aspect_ratio.num; | |
966 | ✗ | reflink->sample_aspect_ratio.den = ref->sample_aspect_ratio.den; | |
967 | ✗ | reflink->colorspace = ref->colorspace; | |
968 | ✗ | reflink->color_range = ref->color_range; | |
969 | |||
970 | ✗ | ret = config_props(outlink); | |
971 | ✗ | if (ret < 0) | |
972 | ✗ | goto err; | |
973 | } | ||
974 | |||
975 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
|
5 | if (scale->eval_mode == EVAL_MODE_FRAME) { |
976 | ✗ | scale->var_values[VAR_REF_N] = rl->frame_count_out; | |
977 | ✗ | scale->var_values[VAR_REF_T] = TS2T(ref->pts, reflink->time_base); | |
978 | #if FF_API_FRAME_PKT | ||
979 | FF_DISABLE_DEPRECATION_WARNINGS | ||
980 | ✗ | scale->var_values[VAR_REF_POS] = ref->pkt_pos == -1 ? NAN : ref->pkt_pos; | |
981 | FF_ENABLE_DEPRECATION_WARNINGS | ||
982 | #endif | ||
983 | } | ||
984 | } | ||
985 | |||
986 | 88985 | ret = scale_frame(ctx->inputs[0], &in, &out); | |
987 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 88985 times.
|
88985 | if (ret < 0) |
988 | ✗ | goto err; | |
989 | |||
990 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 88985 times.
|
88985 | av_assert0(out); |
991 | 88985 | out->pts = av_rescale_q(fs->pts, fs->time_base, outlink->time_base); | |
992 | 88985 | return ff_filter_frame(outlink, out); | |
993 | |||
994 | ✗ | err: | |
995 | ✗ | av_frame_free(&in); | |
996 | ✗ | return ret; | |
997 | } | ||
998 | |||
999 | ✗ | static int filter_frame(AVFilterLink *link, AVFrame *in) | |
1000 | { | ||
1001 | ✗ | AVFilterContext *ctx = link->dst; | |
1002 | ✗ | AVFilterLink *outlink = ctx->outputs[0]; | |
1003 | AVFrame *out; | ||
1004 | int ret; | ||
1005 | |||
1006 | ✗ | ret = scale_frame(link, &in, &out); | |
1007 | ✗ | if (out) | |
1008 | ✗ | return ff_filter_frame(outlink, out); | |
1009 | |||
1010 | ✗ | return ret; | |
1011 | } | ||
1012 | |||
1013 | ✗ | static int filter_frame_ref(AVFilterLink *link, AVFrame *in) | |
1014 | { | ||
1015 | ✗ | FilterLink *l = ff_filter_link(link); | |
1016 | ✗ | ScaleContext *scale = link->dst->priv; | |
1017 | ✗ | AVFilterLink *outlink = link->dst->outputs[1]; | |
1018 | int frame_changed; | ||
1019 | |||
1020 | ✗ | frame_changed = in->width != link->w || | |
1021 | ✗ | in->height != link->h || | |
1022 | ✗ | in->format != link->format || | |
1023 | ✗ | in->sample_aspect_ratio.den != link->sample_aspect_ratio.den || | |
1024 | ✗ | in->sample_aspect_ratio.num != link->sample_aspect_ratio.num || | |
1025 | ✗ | in->colorspace != link->colorspace || | |
1026 | ✗ | in->color_range != link->color_range; | |
1027 | |||
1028 | ✗ | if (frame_changed) { | |
1029 | ✗ | link->format = in->format; | |
1030 | ✗ | link->w = in->width; | |
1031 | ✗ | link->h = in->height; | |
1032 | ✗ | link->sample_aspect_ratio.num = in->sample_aspect_ratio.num; | |
1033 | ✗ | link->sample_aspect_ratio.den = in->sample_aspect_ratio.den; | |
1034 | ✗ | link->colorspace = in->colorspace; | |
1035 | ✗ | link->color_range = in->color_range; | |
1036 | |||
1037 | ✗ | config_props_ref(outlink); | |
1038 | } | ||
1039 | |||
1040 | ✗ | if (scale->eval_mode == EVAL_MODE_FRAME) { | |
1041 | ✗ | scale->var_values[VAR_N] = l->frame_count_out; | |
1042 | ✗ | scale->var_values[VAR_T] = TS2T(in->pts, link->time_base); | |
1043 | #if FF_API_FRAME_PKT | ||
1044 | FF_DISABLE_DEPRECATION_WARNINGS | ||
1045 | ✗ | scale->var_values[VAR_POS] = in->pkt_pos == -1 ? NAN : in->pkt_pos; | |
1046 | FF_ENABLE_DEPRECATION_WARNINGS | ||
1047 | #endif | ||
1048 | } | ||
1049 | |||
1050 | ✗ | return ff_filter_frame(outlink, in); | |
1051 | } | ||
1052 | |||
1053 | ✗ | static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, | |
1054 | char *res, int res_len, int flags) | ||
1055 | { | ||
1056 | ✗ | ScaleContext *scale = ctx->priv; | |
1057 | char *str_expr; | ||
1058 | AVExpr **pexpr_ptr; | ||
1059 | int ret, w, h; | ||
1060 | |||
1061 | ✗ | w = !strcmp(cmd, "width") || !strcmp(cmd, "w"); | |
1062 | ✗ | h = !strcmp(cmd, "height") || !strcmp(cmd, "h"); | |
1063 | |||
1064 | ✗ | if (w || h) { | |
1065 | ✗ | str_expr = w ? scale->w_expr : scale->h_expr; | |
1066 | ✗ | pexpr_ptr = w ? &scale->w_pexpr : &scale->h_pexpr; | |
1067 | |||
1068 | ✗ | ret = scale_parse_expr(ctx, str_expr, pexpr_ptr, cmd, args); | |
1069 | } else | ||
1070 | ✗ | ret = AVERROR(ENOSYS); | |
1071 | |||
1072 | ✗ | if (ret < 0) | |
1073 | ✗ | av_log(ctx, AV_LOG_ERROR, "Failed to process command. Continuing with existing parameters.\n"); | |
1074 | |||
1075 | ✗ | return ret; | |
1076 | } | ||
1077 | |||
1078 | 176944 | static int activate(AVFilterContext *ctx) | |
1079 | { | ||
1080 | 176944 | ScaleContext *scale = ctx->priv; | |
1081 | 176944 | return ff_framesync_activate(&scale->fs); | |
1082 | } | ||
1083 | |||
1084 | ✗ | static const AVClass *child_class_iterate(void **iter) | |
1085 | { | ||
1086 | ✗ | switch ((uintptr_t) *iter) { | |
1087 | ✗ | case 0: | |
1088 | ✗ | *iter = (void*)(uintptr_t) 1; | |
1089 | ✗ | return sws_get_class(); | |
1090 | ✗ | case 1: | |
1091 | ✗ | *iter = (void*)(uintptr_t) 2; | |
1092 | ✗ | return &ff_framesync_class; | |
1093 | } | ||
1094 | |||
1095 | ✗ | return NULL; | |
1096 | } | ||
1097 | |||
1098 | 19986 | static void *child_next(void *obj, void *prev) | |
1099 | { | ||
1100 | 19986 | ScaleContext *s = obj; | |
1101 |
2/2✓ Branch 0 taken 10720 times.
✓ Branch 1 taken 9266 times.
|
19986 | if (!prev) |
1102 | 10720 | return s->sws; | |
1103 |
2/2✓ Branch 0 taken 4633 times.
✓ Branch 1 taken 4633 times.
|
9266 | if (prev == s->sws) |
1104 | 4633 | return &s->fs; | |
1105 | 4633 | return NULL; | |
1106 | } | ||
1107 | |||
1108 | #define OFFSET(x) offsetof(ScaleContext, x) | ||
1109 | #define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM | ||
1110 | #define TFLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_RUNTIME_PARAM | ||
1111 | |||
1112 | static const AVOption scale_options[] = { | ||
1113 | { "w", "Output video width", OFFSET(w_expr), AV_OPT_TYPE_STRING, .flags = TFLAGS }, | ||
1114 | { "width", "Output video width", OFFSET(w_expr), AV_OPT_TYPE_STRING, .flags = TFLAGS }, | ||
1115 | { "h", "Output video height", OFFSET(h_expr), AV_OPT_TYPE_STRING, .flags = TFLAGS }, | ||
1116 | { "height","Output video height", OFFSET(h_expr), AV_OPT_TYPE_STRING, .flags = TFLAGS }, | ||
1117 | { "flags", "Flags to pass to libswscale", OFFSET(flags_str), AV_OPT_TYPE_STRING, { .str = "" }, .flags = FLAGS }, | ||
1118 | { "interl", "set interlacing", OFFSET(interlaced), AV_OPT_TYPE_BOOL, {.i64 = 0 }, -1, 1, FLAGS }, | ||
1119 | { "size", "set video size", OFFSET(size_str), AV_OPT_TYPE_STRING, {.str = NULL}, 0, .flags = FLAGS }, | ||
1120 | { "s", "set video size", OFFSET(size_str), AV_OPT_TYPE_STRING, {.str = NULL}, 0, .flags = FLAGS }, | ||
1121 | { "in_color_matrix", "set input YCbCr type", OFFSET(in_color_matrix), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, AVCOL_SPC_NB-1, .flags = FLAGS, .unit = "color" }, | ||
1122 | { "out_color_matrix", "set output YCbCr type", OFFSET(out_color_matrix), AV_OPT_TYPE_INT, { .i64 = AVCOL_SPC_UNSPECIFIED }, 0, AVCOL_SPC_NB-1, .flags = FLAGS, .unit = "color"}, | ||
1123 | { "auto", NULL, 0, AV_OPT_TYPE_CONST, {.i64=-1}, 0, 0, FLAGS, .unit = "color" }, | ||
1124 | { "bt601", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_SPC_BT470BG}, 0, 0, FLAGS, .unit = "color" }, | ||
1125 | { "bt470", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_SPC_BT470BG}, 0, 0, FLAGS, .unit = "color" }, | ||
1126 | { "smpte170m", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_SPC_BT470BG}, 0, 0, FLAGS, .unit = "color" }, | ||
1127 | { "bt709", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_SPC_BT709}, 0, 0, FLAGS, .unit = "color" }, | ||
1128 | { "fcc", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_SPC_FCC}, 0, 0, FLAGS, .unit = "color" }, | ||
1129 | { "smpte240m", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_SPC_SMPTE240M}, 0, 0, FLAGS, .unit = "color" }, | ||
1130 | { "bt2020", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_SPC_BT2020_NCL}, 0, 0, FLAGS, .unit = "color" }, | ||
1131 | { "in_range", "set input color range", OFFSET( in_range), AV_OPT_TYPE_INT, {.i64 = AVCOL_RANGE_UNSPECIFIED }, 0, 2, FLAGS, .unit = "range" }, | ||
1132 | { "out_range", "set output color range", OFFSET(out_range), AV_OPT_TYPE_INT, {.i64 = AVCOL_RANGE_UNSPECIFIED }, 0, 2, FLAGS, .unit = "range" }, | ||
1133 | { "auto", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_RANGE_UNSPECIFIED }, 0, 0, FLAGS, .unit = "range" }, | ||
1134 | { "unknown", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_RANGE_UNSPECIFIED }, 0, 0, FLAGS, .unit = "range" }, | ||
1135 | { "full", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_RANGE_JPEG}, 0, 0, FLAGS, .unit = "range" }, | ||
1136 | { "limited", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_RANGE_MPEG}, 0, 0, FLAGS, .unit = "range" }, | ||
1137 | { "jpeg", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_RANGE_JPEG}, 0, 0, FLAGS, .unit = "range" }, | ||
1138 | { "mpeg", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_RANGE_MPEG}, 0, 0, FLAGS, .unit = "range" }, | ||
1139 | { "tv", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_RANGE_MPEG}, 0, 0, FLAGS, .unit = "range" }, | ||
1140 | { "pc", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_RANGE_JPEG}, 0, 0, FLAGS, .unit = "range" }, | ||
1141 | { "in_chroma_loc", "set input chroma sample location", OFFSET(in_chroma_loc), AV_OPT_TYPE_INT, { .i64 = AVCHROMA_LOC_UNSPECIFIED }, 0, AVCHROMA_LOC_NB-1, .flags = FLAGS, .unit = "chroma_loc" }, | ||
1142 | { "out_chroma_loc", "set output chroma sample location", OFFSET(out_chroma_loc), AV_OPT_TYPE_INT, { .i64 = AVCHROMA_LOC_UNSPECIFIED }, 0, AVCHROMA_LOC_NB-1, .flags = FLAGS, .unit = "chroma_loc" }, | ||
1143 | {"auto", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCHROMA_LOC_UNSPECIFIED}, 0, 0, FLAGS, .unit = "chroma_loc"}, | ||
1144 | {"unknown", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCHROMA_LOC_UNSPECIFIED}, 0, 0, FLAGS, .unit = "chroma_loc"}, | ||
1145 | {"left", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCHROMA_LOC_LEFT}, 0, 0, FLAGS, .unit = "chroma_loc"}, | ||
1146 | {"center", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCHROMA_LOC_CENTER}, 0, 0, FLAGS, .unit = "chroma_loc"}, | ||
1147 | {"topleft", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCHROMA_LOC_TOPLEFT}, 0, 0, FLAGS, .unit = "chroma_loc"}, | ||
1148 | {"top", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCHROMA_LOC_TOP}, 0, 0, FLAGS, .unit = "chroma_loc"}, | ||
1149 | {"bottomleft", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCHROMA_LOC_BOTTOMLEFT}, 0, 0, FLAGS, .unit = "chroma_loc"}, | ||
1150 | {"bottom", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCHROMA_LOC_BOTTOM}, 0, 0, FLAGS, .unit = "chroma_loc"}, | ||
1151 | { "in_primaries", "set input primaries", OFFSET(in_primaries), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, AVCOL_PRI_NB-1, .flags = FLAGS, .unit = "primaries" }, | ||
1152 | { "out_primaries", "set output primaries", OFFSET(out_primaries), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, AVCOL_PRI_NB-1, .flags = FLAGS, .unit = "primaries"}, | ||
1153 | {"auto", NULL, 0, AV_OPT_TYPE_CONST, {.i64=-1}, 0, 0, FLAGS, .unit = "primaries"}, | ||
1154 | {"bt709", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_PRI_BT709}, 0, 0, FLAGS, .unit = "primaries"}, | ||
1155 | {"bt470m", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_PRI_BT470M}, 0, 0, FLAGS, .unit = "primaries"}, | ||
1156 | {"bt470bg", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_PRI_BT470BG}, 0, 0, FLAGS, .unit = "primaries"}, | ||
1157 | {"smpte170m", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_PRI_SMPTE170M}, 0, 0, FLAGS, .unit = "primaries"}, | ||
1158 | {"smpte240m", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_PRI_SMPTE240M}, 0, 0, FLAGS, .unit = "primaries"}, | ||
1159 | {"film", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_PRI_FILM}, 0, 0, FLAGS, .unit = "primaries"}, | ||
1160 | {"bt2020", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_PRI_BT2020}, 0, 0, FLAGS, .unit = "primaries"}, | ||
1161 | {"smpte428", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_PRI_SMPTE428}, 0, 0, FLAGS, .unit = "primaries"}, | ||
1162 | {"smpte431", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_PRI_SMPTE431}, 0, 0, FLAGS, .unit = "primaries"}, | ||
1163 | {"smpte432", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_PRI_SMPTE432}, 0, 0, FLAGS, .unit = "primaries"}, | ||
1164 | {"jedec-p22", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_PRI_JEDEC_P22}, 0, 0, FLAGS, .unit = "primaries"}, | ||
1165 | {"ebu3213", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_PRI_EBU3213}, 0, 0, FLAGS, .unit = "primaries"}, | ||
1166 | { "in_transfer", "set output color transfer", OFFSET(in_transfer), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, AVCOL_TRC_NB-1, .flags = FLAGS, .unit = "transfer"}, | ||
1167 | {"out_transfer", "set output color transfer", OFFSET(out_transfer), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, AVCOL_TRC_NB-1, .flags = FLAGS, .unit = "transfer"}, | ||
1168 | {"auto", NULL, 0, AV_OPT_TYPE_CONST, {.i64=-1}, 0, 0, FLAGS, .unit = "transfer"}, | ||
1169 | {"bt709", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_TRC_BT709}, 0, 0, FLAGS, .unit = "transfer"}, | ||
1170 | {"bt470m", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_TRC_GAMMA22}, 0, 0, FLAGS, .unit = "transfer"}, | ||
1171 | {"gamma22", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_TRC_GAMMA22}, 0, 0, FLAGS, .unit = "transfer"}, | ||
1172 | {"bt470bg", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_TRC_GAMMA28}, 0, 0, FLAGS, .unit = "transfer"}, | ||
1173 | {"gamma28", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_TRC_GAMMA28}, 0, 0, FLAGS, .unit = "transfer"}, | ||
1174 | {"smpte170m", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_TRC_SMPTE170M}, 0, 0, FLAGS, .unit = "transfer"}, | ||
1175 | {"smpte240m", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_TRC_SMPTE240M}, 0, 0, FLAGS, .unit = "transfer"}, | ||
1176 | {"linear", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_TRC_LINEAR}, 0, 0, FLAGS, .unit = "transfer"}, | ||
1177 | {"iec61966-2-1", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_TRC_IEC61966_2_1}, 0, 0, FLAGS, .unit = "transfer"}, | ||
1178 | {"srgb", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_TRC_IEC61966_2_1}, 0, 0, FLAGS, .unit = "transfer"}, | ||
1179 | {"iec61966-2-4", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_TRC_IEC61966_2_4}, 0, 0, FLAGS, .unit = "transfer"}, | ||
1180 | {"xvycc", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_TRC_IEC61966_2_4}, 0, 0, FLAGS, .unit = "transfer"}, | ||
1181 | {"bt1361e", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_TRC_BT1361_ECG}, 0, 0, FLAGS, .unit = "transfer"}, | ||
1182 | {"bt2020-10", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_TRC_BT2020_10}, 0, 0, FLAGS, .unit = "transfer"}, | ||
1183 | {"bt2020-12", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_TRC_BT2020_12}, 0, 0, FLAGS, .unit = "transfer"}, | ||
1184 | {"smpte2084", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_TRC_SMPTE2084}, 0, 0, FLAGS, .unit = "transfer"}, | ||
1185 | {"smpte428", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_TRC_SMPTE428}, 0, 0, FLAGS, .unit = "transfer"}, | ||
1186 | {"arib-std-b67", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_TRC_ARIB_STD_B67}, 0, 0, FLAGS, .unit = "transfer"}, | ||
1187 | { "in_v_chr_pos", "input vertical chroma position in luma grid/256" , OFFSET(in_v_chr_pos), AV_OPT_TYPE_INT, { .i64 = -513}, -513, 512, FLAGS }, | ||
1188 | { "in_h_chr_pos", "input horizontal chroma position in luma grid/256", OFFSET(in_h_chr_pos), AV_OPT_TYPE_INT, { .i64 = -513}, -513, 512, FLAGS }, | ||
1189 | { "out_v_chr_pos", "output vertical chroma position in luma grid/256" , OFFSET(out_v_chr_pos), AV_OPT_TYPE_INT, { .i64 = -513}, -513, 512, FLAGS }, | ||
1190 | { "out_h_chr_pos", "output horizontal chroma position in luma grid/256", OFFSET(out_h_chr_pos), AV_OPT_TYPE_INT, { .i64 = -513}, -513, 512, FLAGS }, | ||
1191 | { "force_original_aspect_ratio", "decrease or increase w/h if necessary to keep the original AR", OFFSET(force_original_aspect_ratio), AV_OPT_TYPE_INT, { .i64 = 0}, 0, 2, FLAGS, .unit = "force_oar" }, | ||
1192 | { "disable", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 0 }, 0, 0, FLAGS, .unit = "force_oar" }, | ||
1193 | { "decrease", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 1 }, 0, 0, FLAGS, .unit = "force_oar" }, | ||
1194 | { "increase", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 2 }, 0, 0, FLAGS, .unit = "force_oar" }, | ||
1195 | { "force_divisible_by", "enforce that the output resolution is divisible by a defined integer when force_original_aspect_ratio is used", OFFSET(force_divisible_by), AV_OPT_TYPE_INT, { .i64 = 1}, 1, 256, FLAGS }, | ||
1196 | { "reset_sar", "reset SAR to 1 and scale to square pixels if scaling proportionally", OFFSET(reset_sar), AV_OPT_TYPE_BOOL, { .i64 = 0}, 0, 1, FLAGS }, | ||
1197 | { "param0", "Scaler param 0", OFFSET(param[0]), AV_OPT_TYPE_DOUBLE, { .dbl = DBL_MAX }, -DBL_MAX, DBL_MAX, FLAGS }, | ||
1198 | { "param1", "Scaler param 1", OFFSET(param[1]), AV_OPT_TYPE_DOUBLE, { .dbl = DBL_MAX }, -DBL_MAX, DBL_MAX, FLAGS }, | ||
1199 | { "eval", "specify when to evaluate expressions", OFFSET(eval_mode), AV_OPT_TYPE_INT, {.i64 = EVAL_MODE_INIT}, 0, EVAL_MODE_NB-1, FLAGS, .unit = "eval" }, | ||
1200 | { "init", "eval expressions once during initialization", 0, AV_OPT_TYPE_CONST, {.i64=EVAL_MODE_INIT}, .flags = FLAGS, .unit = "eval" }, | ||
1201 | { "frame", "eval expressions during initialization and per-frame", 0, AV_OPT_TYPE_CONST, {.i64=EVAL_MODE_FRAME}, .flags = FLAGS, .unit = "eval" }, | ||
1202 | { NULL } | ||
1203 | }; | ||
1204 | |||
1205 | static const AVClass scale_class = { | ||
1206 | .class_name = "scale", | ||
1207 | .item_name = av_default_item_name, | ||
1208 | .option = scale_options, | ||
1209 | .version = LIBAVUTIL_VERSION_INT, | ||
1210 | .category = AV_CLASS_CATEGORY_FILTER, | ||
1211 | .child_class_iterate = child_class_iterate, | ||
1212 | .child_next = child_next, | ||
1213 | }; | ||
1214 | |||
1215 | static const AVFilterPad avfilter_vf_scale_inputs[] = { | ||
1216 | { | ||
1217 | .name = "default", | ||
1218 | .type = AVMEDIA_TYPE_VIDEO, | ||
1219 | }, | ||
1220 | }; | ||
1221 | |||
1222 | static const AVFilterPad avfilter_vf_scale_outputs[] = { | ||
1223 | { | ||
1224 | .name = "default", | ||
1225 | .type = AVMEDIA_TYPE_VIDEO, | ||
1226 | .config_props = config_props, | ||
1227 | }, | ||
1228 | }; | ||
1229 | |||
1230 | const FFFilter ff_vf_scale = { | ||
1231 | .p.name = "scale", | ||
1232 | .p.description = NULL_IF_CONFIG_SMALL("Scale the input video size and/or convert the image format."), | ||
1233 | .p.priv_class = &scale_class, | ||
1234 | .p.flags = AVFILTER_FLAG_DYNAMIC_INPUTS, | ||
1235 | .preinit = preinit, | ||
1236 | .init = init, | ||
1237 | .uninit = uninit, | ||
1238 | .priv_size = sizeof(ScaleContext), | ||
1239 | FILTER_INPUTS(avfilter_vf_scale_inputs), | ||
1240 | FILTER_OUTPUTS(avfilter_vf_scale_outputs), | ||
1241 | FILTER_QUERY_FUNC2(query_formats), | ||
1242 | .activate = activate, | ||
1243 | .process_command = process_command, | ||
1244 | }; | ||
1245 | |||
1246 | ✗ | static const AVClass *scale2ref_child_class_iterate(void **iter) | |
1247 | { | ||
1248 | ✗ | const AVClass *c = *iter ? NULL : sws_get_class(); | |
1249 | ✗ | *iter = (void*)(uintptr_t)c; | |
1250 | ✗ | return c; | |
1251 | } | ||
1252 | |||
1253 | ✗ | static void *scale2ref_child_next(void *obj, void *prev) | |
1254 | { | ||
1255 | ✗ | ScaleContext *s = obj; | |
1256 | ✗ | if (!prev) | |
1257 | ✗ | return s->sws; | |
1258 | ✗ | return NULL; | |
1259 | } | ||
1260 | |||
1261 | static const AVClass scale2ref_class = { | ||
1262 | .class_name = "scale(2ref)", | ||
1263 | .item_name = av_default_item_name, | ||
1264 | .option = scale_options, | ||
1265 | .version = LIBAVUTIL_VERSION_INT, | ||
1266 | .category = AV_CLASS_CATEGORY_FILTER, | ||
1267 | .child_class_iterate = scale2ref_child_class_iterate, | ||
1268 | .child_next = scale2ref_child_next, | ||
1269 | }; | ||
1270 | |||
1271 | static const AVFilterPad avfilter_vf_scale2ref_inputs[] = { | ||
1272 | { | ||
1273 | .name = "default", | ||
1274 | .type = AVMEDIA_TYPE_VIDEO, | ||
1275 | .filter_frame = filter_frame, | ||
1276 | }, | ||
1277 | { | ||
1278 | .name = "ref", | ||
1279 | .type = AVMEDIA_TYPE_VIDEO, | ||
1280 | .filter_frame = filter_frame_ref, | ||
1281 | }, | ||
1282 | }; | ||
1283 | |||
1284 | static const AVFilterPad avfilter_vf_scale2ref_outputs[] = { | ||
1285 | { | ||
1286 | .name = "default", | ||
1287 | .type = AVMEDIA_TYPE_VIDEO, | ||
1288 | .config_props = config_props, | ||
1289 | .request_frame= request_frame, | ||
1290 | }, | ||
1291 | { | ||
1292 | .name = "ref", | ||
1293 | .type = AVMEDIA_TYPE_VIDEO, | ||
1294 | .config_props = config_props_ref, | ||
1295 | .request_frame= request_frame_ref, | ||
1296 | }, | ||
1297 | }; | ||
1298 | |||
1299 | const FFFilter ff_vf_scale2ref = { | ||
1300 | .p.name = "scale2ref", | ||
1301 | .p.description = NULL_IF_CONFIG_SMALL("Scale the input video size and/or convert the image format to the given reference."), | ||
1302 | .p.priv_class = &scale2ref_class, | ||
1303 | .preinit = preinit, | ||
1304 | .init = init, | ||
1305 | .uninit = uninit, | ||
1306 | .priv_size = sizeof(ScaleContext), | ||
1307 | FILTER_INPUTS(avfilter_vf_scale2ref_inputs), | ||
1308 | FILTER_OUTPUTS(avfilter_vf_scale2ref_outputs), | ||
1309 | FILTER_QUERY_FUNC2(query_formats), | ||
1310 | .process_command = process_command, | ||
1311 | }; | ||
1312 |