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 "ohsub",
55 "ovsub",
57 };
58
72 };
73
77 struct SwsContext *
isws[2];
///< software scaler context for interlaced material
79
80 /**
81 * New dimensions. Special values are:
82 * 0 = original width/height
83 * -1 = keep original aspect
84 * -N = try to keep aspect but make sure it is divisible by N
85 */
88 unsigned int flags;
///sws flags
89
91 int slice_y;
///< top of current output slice
95
96 char *
w_expr;
///< width expression string
97 char *
h_expr;
///< height expression string
99
102
105
110
113
115 {
118
121 "Size and width/height expressions cannot be set at the same time.\n");
123 }
124
127
132 "Invalid size '%s'\n", scale->
size_str);
134 }
135 snprintf(buf,
sizeof(buf)-1,
"%d", scale->
w);
137 snprintf(buf,
sizeof(buf)-1,
"%d", scale->
h);
139 }
144
147
149
155 if (ret < 0)
157 }
160
161 return 0;
162 }
163
165 {
172 }
173
175 {
179
190 }
191 }
193 }
204 }
205 }
207 }
208
209 return 0;
210 }
211
213 {
214 if (!s)
215 s = "bt601";
216
217 if (s && strstr(s, "bt709")) {
219 } else if (s && strstr(s, "fcc")) {
221 } else if (s && strstr(s, "smpte240m")) {
223 } else if (s && (strstr(s, "bt601") || strstr(s, "bt470") || strstr(s, "smpte170m"))) {
225 }
226
227 if (colorspace < 1 || colorspace > 7) {
229 }
230
232 }
233
235 {
242 int64_t w, h;
243 double var_values[
VARS_NB], res;
244 char *expr;
246 int factor_w, factor_h;
247
252 var_values[
VAR_A] = (double) inlink->
w / inlink->
h;
260
261 /* evaluate width and height */
269 goto fail;
271 /* evaluate again the width, as it may depend on the output height */
275 goto fail;
277
280
281 /* Check if it is requested that the result has to be divisible by a some
282 * factor (w or h = -n with n being the factor). */
283 factor_w = 1;
284 factor_h = 1;
285 if (w < -1) {
286 factor_w = -w;
287 }
288 if (h < -1) {
289 factor_h = -h;
290 }
291
292 if (w < 0 && h < 0)
293 scale->
w = scale->
h = 0;
294
299
300 /* Make sure that the result is divisible by the factor we determined
301 * earlier. If no factor was set, it is nothing will happen as the default
302 * factor is 1 */
303 if (w < 0)
304 w =
av_rescale(h, inlink->
w, inlink->
h * factor_w) * factor_w;
305 if (h < 0)
306 h =
av_rescale(w, inlink->
h, inlink->
w * factor_h) * factor_h;
307
308 /* Note that force_original_aspect_ratio may overwrite the previous set
309 * dimensions so that it is not divisible by the set factors anymore. */
313
317 } else {
320 }
321 }
322
323 if (w > INT_MAX || h > INT_MAX ||
324 (h * inlink->
w) > INT_MAX ||
325 (w * inlink->
h) > INT_MAX)
327
330
331 /* TODO: make algorithm configurable */
332
338
346 if (inlink->
w == outlink->
w && inlink->
h == outlink->
h &&
348 ;
349 else {
351 int i;
352
353 for (i = 0; i < 3; i++) {
356 if (!*s)
358
361
365 }
366 }
367
375
376 /* Override YUV420P settings to have the correct (MPEG-2) chroma positions
377 * MPEG-2 chroma positions are used by convention
378 * XXX: support other 4:2:0 pixel formats */
380 scale->
in_v_chr_pos = (i == 0) ? 128 : (i == 1) ? 64 : 192;
381 }
382
385 }
386
391
395 break;
396 }
397 }
398
401 } else
403
404 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",
410 return 0;
411
412 fail:
414 "Error when evaluating the expression '%s'.\n"
415 "Maybe the expression for out_w:'%s' or for out_h:'%s' is self-referencing.\n",
418 }
419
421 {
425 int in_stride[4],out_stride[4];
426 int i;
427
428 for(i=0; i<4; i++){
429 int vsub= ((i+1)&2) ? scale->
vsub : 0;
430 in_stride[i] = cur_pic->
linesize[i] * mul;
431 out_stride[i] = out_buf->
linesize[i] * mul;
432 in[i] = cur_pic->
data[i] + ((y>>vsub)+field) * cur_pic->
linesize[i];
433 out[i] = out_buf->
data[i] + field * out_buf->
linesize[i];
434 }
436 in[1] = cur_pic->
data[1];
438 out[1] = out_buf->
data[1];
439
440 return sws_scale(sws, in, in_stride, y/mul, h,
441 out,out_stride);
442 }
443
445 {
451 int in_range;
452
457 snprintf(buf,
sizeof(buf)-1,
"%d", outlink->
w);
459 snprintf(buf,
sizeof(buf)-1,
"%d", outlink->
h);
461
465
468 }
469
472
475
477 if (!out) {
480 }
481
485
488
490
497 const int *inv_table, *
table;
498
500 (int **)&table, &out_full,
501 &brightness, &contrast, &saturation);
502
507
514
516 table, out_full,
517 brightness, contrast, saturation);
520 table, out_full,
521 brightness, contrast, saturation);
524 table, out_full,
525 brightness, contrast, saturation);
526 }
527
531 INT_MAX);
532
536 }else{
538 }
539
542 }
543
545 {
547 }
548
549 #define OFFSET(x) offsetof(ScaleContext, x)
550 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
551
571 {
"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 },
572 {
"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 },
573 {
"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 },
574 {
"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 },
575 {
"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" },
580 };
581
589 };
590
592 {
596 },
598 };
599
601 {
605 },
607 };
608
611 .description =
NULL_IF_CONFIG_SMALL(
"Scale the input video size and/or convert the image format."),
616 .priv_class = &scale_class,
617 .
inputs = avfilter_vf_scale_inputs,
618 .
outputs = avfilter_vf_scale_outputs,
619 };