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 <stdio.h>
27 #include <string.h>
28
43
45 "in_w", "iw",
46 "in_h", "ih",
47 "out_w", "ow",
48 "out_h", "oh",
49 "a",
50 "sar",
51 "dar",
52 "hsub",
53 "vsub",
54 NULL
55 };
56
68 };
69
73 struct SwsContext *isws[2];
///< software scaler context for interlaced material
75
76 /**
77 * New dimensions. Special values are:
78 * 0 = original width/height
79 * -1 = keep original aspect
80 */
83 unsigned int flags;
///sws flags
84
85 int hsub,
vsub;
///< chroma subsampling
86 int slice_y;
///< top of current output slice
90
91 char *
w_expr;
///< width expression string
92 char *
h_expr;
///< height expression string
94
97
100
105
108
110 {
113
116 "Size and width/height expressions cannot be set at the same time.\n");
118 }
119
122
127 "Invalid size '%s'\n", scale->
size_str);
129 }
130 snprintf(buf,
sizeof(buf)-1,
"%d", scale->
w);
132 snprintf(buf,
sizeof(buf)-1,
"%d", scale->
h);
134 }
139
142
144
150 if (ret < 0)
152 }
154 *opts = NULL;
155
156 return 0;
157 }
158
160 {
167 }
168
170 {
174
176 formats = NULL;
183 }
185 }
187 formats = NULL;
194 }
196 }
197
198 return 0;
199 }
200
202 {
203 if (!s)
204 s = "bt601";
205
206 if (s && strstr(s, "bt709")) {
208 } else if (s && strstr(s, "fcc")) {
210 } else if (s && strstr(s, "smpte240m")) {
212 } else if (s && (strstr(s, "bt601") || strstr(s, "bt470") || strstr(s, "smpte170m"))) {
214 }
215
216 if (colorspace < 1 || colorspace > 7) {
218 }
219
221 }
222
224 {
230 int64_t w, h;
232 char *expr;
234
239 var_values[
VAR_A] = (double) inlink->
w / inlink->
h;
245
246 /* evaluate width and height */
249 NULL, NULL, NULL, NULL, NULL, 0, ctx);
253 NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0)
254 goto fail;
256 /* evaluate again the width, as it may depend on the output height */
259 NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0)
260 goto fail;
262
265
266 /* sanity check params */
267 if (w < -1 || h < -1) {
270 }
271 if (w == -1 && h == -1)
272 scale->
w = scale->
h = 0;
273
278 if (w == -1)
280 if (h == -1)
282
286
290 } else {
293 }
294 }
295
296 if (w > INT_MAX || h > INT_MAX ||
297 (h * inlink->
w) > INT_MAX ||
298 (w * inlink->
h) > INT_MAX)
300
303
304 /* TODO: make algorithm configurable */
305
311
318 scale->
isws[0] = scale->
isws[1] = scale->
sws = NULL;
319 if (inlink->
w == outlink->
w && inlink->
h == outlink->
h &&
321 ;
322 else {
324 int i;
325
326 for (i = 0; i < 3; i++) {
329 if (!*s)
331
334
338 }
339 }
340
348
353
357 break;
358 }
359 }
360
363 } else
365
366 av_log(ctx,
AV_LOG_VERBOSE,
"w:%d h:%d fmt:%s sar:%d/%d -> w:%d h:%d fmt:%s sar:%d/%d flags:0x%0x\n",
372 return 0;
373
374 fail:
376 "Error when evaluating the expression '%s'.\n"
377 "Maybe the expression for out_w:'%s' or for out_h:'%s' is self-referencing.\n",
380 }
381
383 {
387 int in_stride[4],out_stride[4];
388 int i;
389
390 for(i=0; i<4; i++){
391 int vsub= ((i+1)&2) ? scale->
vsub : 0;
392 in_stride[i] = cur_pic->
linesize[i] * mul;
393 out_stride[i] = out_buf->
linesize[i] * mul;
394 in[i] = cur_pic->
data[i] + ((y>>vsub)+field) * cur_pic->
linesize[i];
395 out[i] = out_buf->
data[i] + field * out_buf->
linesize[i];
396 }
398 in[1] = cur_pic->
data[1];
400 out[1] = out_buf->
data[1];
401
402 return sws_scale(sws, in, in_stride, y/mul, h,
403 out,out_stride);
404 }
405
407 {
414
419 snprintf(buf,
sizeof(buf)-1,
"%d", outlink->
w);
421 snprintf(buf,
sizeof(buf)-1,
"%d", outlink->
h);
423
427
430 }
431
434
437
439 if (!out) {
442 }
443
447
450
452
459 const int *inv_table, *
table;
460
462 (int **)&table, &out_full,
463 &brightness, &contrast, &saturation);
464
469
476
478 table, out_full,
479 brightness, contrast, saturation);
482 table, out_full,
483 brightness, contrast, saturation);
486 table, out_full,
487 brightness, contrast, saturation);
488 }
489
493 INT_MAX);
494
498 }else{
500 }
501
504 }
505
507 {
509 }
510
511 #define OFFSET(x) offsetof(ScaleContext, x)
512 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
513
533 {
"in_v_chr_pos",
"input vertical chroma position in luma grid/256" ,
OFFSET(in_v_chr_pos),
AV_OPT_TYPE_INT, { .i64 = -1}, -1, 512,
FLAGS },
534 {
"in_h_chr_pos",
"input horizontal chroma position in luma grid/256",
OFFSET(in_h_chr_pos),
AV_OPT_TYPE_INT, { .i64 = -1}, -1, 512,
FLAGS },
535 {
"out_v_chr_pos",
"output vertical chroma position in luma grid/256" ,
OFFSET(out_v_chr_pos),
AV_OPT_TYPE_INT, { .i64 = -1}, -1, 512,
FLAGS },
536 {
"out_h_chr_pos",
"output horizontal chroma position in luma grid/256",
OFFSET(out_h_chr_pos),
AV_OPT_TYPE_INT, { .i64 = -1}, -1, 512,
FLAGS },
537 {
"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,
"force_oar" },
541 { NULL }
542 };
543
550 };
551
553 {
557 },
558 { NULL }
559 };
560
562 {
566 },
567 { NULL }
568 };
569
572 .description =
NULL_IF_CONFIG_SMALL(
"Scale the input video size and/or convert the image format."),
577 .priv_class = &scale_class,
578 .
inputs = avfilter_vf_scale_inputs,
579 .
outputs = avfilter_vf_scale_outputs,
580 };