FFmpeg
vf_scale.c
Go to the documentation of this file.
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"
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 {
101 #if FF_API_FRAME_PKT
102  VAR_POS,
103 #endif
125 };
126 
127 enum EvalMode {
131 };
132 
133 typedef struct ScaleContext {
134  const AVClass *class;
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
151  int uses_ref;
152 
153  char *w_expr; ///< width expression string
154  char *h_expr; ///< height expression string
158 
159  char *flags_str;
160 
163 
164  int in_range;
166 
173 
176 
177  int eval_mode; ///< expression evaluation mode
178 
179 } ScaleContext;
180 
182 
183 static int config_props(AVFilterLink *outlink);
184 
186 {
187  ScaleContext *scale = ctx->priv;
188  unsigned vars_w[VARS_NB] = { 0 }, vars_h[VARS_NB] = { 0 };
189 
190  if (!scale->w_pexpr && !scale->h_pexpr)
191  return AVERROR(EINVAL);
192 
193  if (scale->w_pexpr)
194  av_expr_count_vars(scale->w_pexpr, vars_w, VARS_NB);
195  if (scale->h_pexpr)
196  av_expr_count_vars(scale->h_pexpr, vars_h, VARS_NB);
197 
198  if (vars_w[VAR_OUT_W] || vars_w[VAR_OW]) {
199  av_log(ctx, AV_LOG_ERROR, "Width expression cannot be self-referencing: '%s'.\n", scale->w_expr);
200  return AVERROR(EINVAL);
201  }
202 
203  if (vars_h[VAR_OUT_H] || vars_h[VAR_OH]) {
204  av_log(ctx, AV_LOG_ERROR, "Height expression cannot be self-referencing: '%s'.\n", scale->h_expr);
205  return AVERROR(EINVAL);
206  }
207 
208  if ((vars_w[VAR_OUT_H] || vars_w[VAR_OH]) &&
209  (vars_h[VAR_OUT_W] || vars_h[VAR_OW])) {
210  av_log(ctx, AV_LOG_WARNING, "Circular references detected for width '%s' and height '%s' - possibly invalid.\n", scale->w_expr, scale->h_expr);
211  }
212 
213  if (vars_w[VAR_REF_W] || vars_h[VAR_REF_W] ||
214  vars_w[VAR_RW] || vars_h[VAR_RW] ||
215  vars_w[VAR_REF_H] || vars_h[VAR_REF_H] ||
216  vars_w[VAR_RH] || vars_h[VAR_RH] ||
217  vars_w[VAR_REF_A] || vars_h[VAR_REF_A] ||
218  vars_w[VAR_REF_SAR] || vars_h[VAR_REF_SAR] ||
219  vars_w[VAR_REF_DAR] || vars_h[VAR_REF_DAR] ||
220  vars_w[VAR_RDAR] || vars_h[VAR_RDAR] ||
221  vars_w[VAR_REF_HSUB] || vars_h[VAR_REF_HSUB] ||
222  vars_w[VAR_REF_VSUB] || vars_h[VAR_REF_VSUB] ||
223  vars_w[VAR_REF_N] || vars_h[VAR_REF_N] ||
224  vars_w[VAR_REF_T] || vars_h[VAR_REF_T] ||
225  vars_w[VAR_REF_POS] || vars_h[VAR_REF_POS]) {
226  scale->uses_ref = 1;
227  }
228 
229  if (ctx->filter != &ff_vf_scale2ref &&
230  (vars_w[VAR_S2R_MAIN_W] || vars_h[VAR_S2R_MAIN_W] ||
231  vars_w[VAR_S2R_MAIN_H] || vars_h[VAR_S2R_MAIN_H] ||
232  vars_w[VAR_S2R_MAIN_A] || vars_h[VAR_S2R_MAIN_A] ||
233  vars_w[VAR_S2R_MAIN_SAR] || vars_h[VAR_S2R_MAIN_SAR] ||
234  vars_w[VAR_S2R_MAIN_DAR] || vars_h[VAR_S2R_MAIN_DAR] ||
235  vars_w[VAR_S2R_MDAR] || vars_h[VAR_S2R_MDAR] ||
236  vars_w[VAR_S2R_MAIN_HSUB] || vars_h[VAR_S2R_MAIN_HSUB] ||
237  vars_w[VAR_S2R_MAIN_VSUB] || vars_h[VAR_S2R_MAIN_VSUB] ||
238  vars_w[VAR_S2R_MAIN_N] || vars_h[VAR_S2R_MAIN_N] ||
239  vars_w[VAR_S2R_MAIN_T] || vars_h[VAR_S2R_MAIN_T] ||
240  vars_w[VAR_S2R_MAIN_POS] || vars_h[VAR_S2R_MAIN_POS]) ) {
241  av_log(ctx, AV_LOG_ERROR, "Expressions with scale2ref variables are not valid in scale filter.\n");
242  return AVERROR(EINVAL);
243  }
244 
245  if (ctx->filter != &ff_vf_scale2ref &&
246  (vars_w[VAR_S2R_MAIN_W] || vars_h[VAR_S2R_MAIN_W] ||
247  vars_w[VAR_S2R_MAIN_H] || vars_h[VAR_S2R_MAIN_H] ||
248  vars_w[VAR_S2R_MAIN_A] || vars_h[VAR_S2R_MAIN_A] ||
249  vars_w[VAR_S2R_MAIN_SAR] || vars_h[VAR_S2R_MAIN_SAR] ||
250  vars_w[VAR_S2R_MAIN_DAR] || vars_h[VAR_S2R_MAIN_DAR] ||
251  vars_w[VAR_S2R_MDAR] || vars_h[VAR_S2R_MDAR] ||
252  vars_w[VAR_S2R_MAIN_HSUB] || vars_h[VAR_S2R_MAIN_HSUB] ||
253  vars_w[VAR_S2R_MAIN_VSUB] || vars_h[VAR_S2R_MAIN_VSUB] ||
254  vars_w[VAR_S2R_MAIN_N] || vars_h[VAR_S2R_MAIN_N] ||
255  vars_w[VAR_S2R_MAIN_T] || vars_h[VAR_S2R_MAIN_T] ||
256  vars_w[VAR_S2R_MAIN_POS] || vars_h[VAR_S2R_MAIN_POS]) ) {
257  av_log(ctx, AV_LOG_ERROR, "Expressions with scale2ref variables are not valid in scale filter.\n");
258  return AVERROR(EINVAL);
259  }
260 
261  if (scale->eval_mode == EVAL_MODE_INIT &&
262  (vars_w[VAR_N] || vars_h[VAR_N] ||
263  vars_w[VAR_T] || vars_h[VAR_T] ||
265  vars_w[VAR_POS] || vars_h[VAR_POS] ||
266 #endif
267  vars_w[VAR_S2R_MAIN_N] || vars_h[VAR_S2R_MAIN_N] ||
268  vars_w[VAR_S2R_MAIN_T] || vars_h[VAR_S2R_MAIN_T] ||
269  vars_w[VAR_S2R_MAIN_POS] || vars_h[VAR_S2R_MAIN_POS]) ) {
270  av_log(ctx, AV_LOG_ERROR, "Expressions with frame variables 'n', 't', 'pos' are not valid in init eval_mode.\n");
271  return AVERROR(EINVAL);
272  }
273 
274  return 0;
275 }
276 
277 static int scale_parse_expr(AVFilterContext *ctx, char *str_expr, AVExpr **pexpr_ptr, const char *var, const char *args)
278 {
279  ScaleContext *scale = ctx->priv;
280  int ret, is_inited = 0;
281  char *old_str_expr = NULL;
282  AVExpr *old_pexpr = NULL;
283 
284  if (str_expr) {
285  old_str_expr = av_strdup(str_expr);
286  if (!old_str_expr)
287  return AVERROR(ENOMEM);
288  av_opt_set(scale, var, args, 0);
289  }
290 
291  if (*pexpr_ptr) {
292  old_pexpr = *pexpr_ptr;
293  *pexpr_ptr = NULL;
294  is_inited = 1;
295  }
296 
297  ret = av_expr_parse(pexpr_ptr, args, var_names,
298  NULL, NULL, NULL, NULL, 0, ctx);
299  if (ret < 0) {
300  av_log(ctx, AV_LOG_ERROR, "Cannot parse expression for %s: '%s'\n", var, args);
301  goto revert;
302  }
303 
304  ret = check_exprs(ctx);
305  if (ret < 0)
306  goto revert;
307 
308  if (is_inited && (ret = config_props(ctx->outputs[0])) < 0)
309  goto revert;
310 
311  av_expr_free(old_pexpr);
312  old_pexpr = NULL;
313  av_freep(&old_str_expr);
314 
315  return 0;
316 
317 revert:
318  av_expr_free(*pexpr_ptr);
319  *pexpr_ptr = NULL;
320  if (old_str_expr) {
321  av_opt_set(scale, var, old_str_expr, 0);
322  av_free(old_str_expr);
323  }
324  if (old_pexpr)
325  *pexpr_ptr = old_pexpr;
326 
327  return ret;
328 }
329 
331 {
332  ScaleContext *scale = ctx->priv;
333 
334  scale->sws = sws_alloc_context();
335  if (!scale->sws)
336  return AVERROR(ENOMEM);
337 
338  // set threads=0, so we can later check whether the user modified it
339  scale->sws->threads = 0;
340 
342 
343  return 0;
344 }
345 
346 static int do_scale(FFFrameSync *fs);
347 
349 {
350  ScaleContext *scale = ctx->priv;
351  int ret;
352 
353  if (ctx->filter == &ff_vf_scale2ref)
354  av_log(ctx, AV_LOG_WARNING, "scale2ref is deprecated, use scale=rw:rh instead\n");
355 
356  if (scale->size_str && (scale->w_expr || scale->h_expr)) {
358  "Size and width/height expressions cannot be set at the same time.\n");
359  return AVERROR(EINVAL);
360  }
361 
362  if (scale->w_expr && !scale->h_expr)
363  FFSWAP(char *, scale->w_expr, scale->size_str);
364 
365  if (scale->size_str) {
366  char buf[32];
367  if ((ret = av_parse_video_size(&scale->w, &scale->h, scale->size_str)) < 0) {
369  "Invalid size '%s'\n", scale->size_str);
370  return ret;
371  }
372  snprintf(buf, sizeof(buf)-1, "%d", scale->w);
373  av_opt_set(scale, "w", buf, 0);
374  snprintf(buf, sizeof(buf)-1, "%d", scale->h);
375  av_opt_set(scale, "h", buf, 0);
376  }
377  if (!scale->w_expr)
378  av_opt_set(scale, "w", "iw", 0);
379  if (!scale->h_expr)
380  av_opt_set(scale, "h", "ih", 0);
381 
382  ret = scale_parse_expr(ctx, NULL, &scale->w_pexpr, "width", scale->w_expr);
383  if (ret < 0)
384  return ret;
385 
386  ret = scale_parse_expr(ctx, NULL, &scale->h_pexpr, "height", scale->h_expr);
387  if (ret < 0)
388  return ret;
389 
390  if (scale->in_color_matrix != -1 && !sws_test_colorspace(scale->in_color_matrix, 0)) {
391  av_log(ctx, AV_LOG_ERROR, "Unsupported input color matrix '%s'\n",
392  av_color_space_name(scale->in_color_matrix));
393  return AVERROR(EINVAL);
394  }
395 
396  if (scale->out_color_matrix != -1 && !sws_test_colorspace(scale->out_color_matrix, 1)) {
397  av_log(ctx, AV_LOG_ERROR, "Unsupported output color matrix '%s'\n",
398  av_color_space_name(scale->out_color_matrix));
399  return AVERROR(EINVAL);
400  }
401 
402  av_log(ctx, AV_LOG_VERBOSE, "w:%s h:%s flags:'%s' interl:%d\n",
403  scale->w_expr, scale->h_expr, (char *)av_x_if_null(scale->flags_str, ""), scale->interlaced);
404 
405  if (scale->flags_str && *scale->flags_str) {
406  ret = av_opt_set(scale->sws, "sws_flags", scale->flags_str, 0);
407  if (ret < 0)
408  return ret;
409  }
410 
411  for (int i = 0; i < FF_ARRAY_ELEMS(scale->param); i++)
412  if (scale->param[i] != DBL_MAX)
413  scale->sws->scaler_params[i] = scale->param[i];
414 
415  scale->sws->src_h_chr_pos = scale->in_h_chr_pos;
416  scale->sws->src_v_chr_pos = scale->in_v_chr_pos;
417  scale->sws->dst_h_chr_pos = scale->out_h_chr_pos;
418  scale->sws->dst_v_chr_pos = scale->out_v_chr_pos;
419 
420  // use generic thread-count if the user did not set it explicitly
421  if (!scale->sws->threads)
422  scale->sws->threads = ff_filter_get_nb_threads(ctx);
423 
424  if (ctx->filter != &ff_vf_scale2ref && scale->uses_ref) {
425  AVFilterPad pad = {
426  .name = "ref",
427  .type = AVMEDIA_TYPE_VIDEO,
428  };
429  ret = ff_append_inpad(ctx, &pad);
430  if (ret < 0)
431  return ret;
432  }
433 
434  return 0;
435 }
436 
438 {
439  ScaleContext *scale = ctx->priv;
440  av_expr_free(scale->w_pexpr);
441  av_expr_free(scale->h_pexpr);
442  scale->w_pexpr = scale->h_pexpr = NULL;
444  sws_free_context(&scale->sws);
445 }
446 
448  AVFilterFormatsConfig **cfg_in,
449  AVFilterFormatsConfig **cfg_out)
450 {
451  const ScaleContext *scale = ctx->priv;
453  const AVPixFmtDescriptor *desc;
454  enum AVPixelFormat pix_fmt;
455  int ret;
456 
457  desc = NULL;
458  formats = NULL;
459  while ((desc = av_pix_fmt_desc_next(desc))) {
461  if (sws_test_format(pix_fmt, 0)) {
462  if ((ret = ff_add_format(&formats, pix_fmt)) < 0)
463  return ret;
464  }
465  }
466  if ((ret = ff_formats_ref(formats, &cfg_in[0]->formats)) < 0)
467  return ret;
468 
469  desc = NULL;
470  formats = NULL;
471  while ((desc = av_pix_fmt_desc_next(desc))) {
474  if ((ret = ff_add_format(&formats, pix_fmt)) < 0)
475  return ret;
476  }
477  }
478  if ((ret = ff_formats_ref(formats, &cfg_out[0]->formats)) < 0)
479  return ret;
480 
481  /* accept all supported inputs, even if user overrides their properties */
483  for (int i = 0; i < formats->nb_formats; i++) {
484  if (!sws_test_colorspace(formats->formats[i], 0)) {
485  for (int j = i--; j + 1 < formats->nb_formats; j++)
486  formats->formats[j] = formats->formats[j + 1];
487  formats->nb_formats--;
488  }
489  }
490  if ((ret = ff_formats_ref(formats, &cfg_in[0]->color_spaces)) < 0)
491  return ret;
492 
494  &cfg_in[0]->color_ranges)) < 0)
495  return ret;
496 
497  /* propagate output properties if overridden */
498  if (scale->out_color_matrix != AVCOL_SPC_UNSPECIFIED) {
499  formats = ff_make_formats_list_singleton(scale->out_color_matrix);
500  } else {
502  for (int i = 0; i < formats->nb_formats; i++) {
503  if (!sws_test_colorspace(formats->formats[i], 1)) {
504  for (int j = i--; j + 1 < formats->nb_formats; j++)
505  formats->formats[j] = formats->formats[j + 1];
506  formats->nb_formats--;
507  }
508  }
509  }
510  if ((ret = ff_formats_ref(formats, &cfg_out[0]->color_spaces)) < 0)
511  return ret;
512 
513  formats = scale->out_range != AVCOL_RANGE_UNSPECIFIED
516  if ((ret = ff_formats_ref(formats, &cfg_out[0]->color_ranges)) < 0)
517  return ret;
518 
519  return 0;
520 }
521 
523 {
524  ScaleContext *scale = ctx->priv;
525  const char scale2ref = ctx->filter == &ff_vf_scale2ref;
526  const AVFilterLink *inlink = scale2ref ? ctx->inputs[1] : ctx->inputs[0];
527  const AVFilterLink *outlink = ctx->outputs[0];
529  const AVPixFmtDescriptor *out_desc = av_pix_fmt_desc_get(outlink->format);
530  char *expr;
531  int eval_w, eval_h;
532  int ret;
533  double res;
534  const AVPixFmtDescriptor *main_desc;
535  const AVFilterLink *main_link;
536 
537  if (scale2ref) {
538  main_link = ctx->inputs[0];
539  main_desc = av_pix_fmt_desc_get(main_link->format);
540  }
541 
542  scale->var_values[VAR_IN_W] = scale->var_values[VAR_IW] = inlink->w;
543  scale->var_values[VAR_IN_H] = scale->var_values[VAR_IH] = inlink->h;
544  scale->var_values[VAR_OUT_W] = scale->var_values[VAR_OW] = NAN;
545  scale->var_values[VAR_OUT_H] = scale->var_values[VAR_OH] = NAN;
546  scale->var_values[VAR_A] = (double) inlink->w / inlink->h;
547  scale->var_values[VAR_SAR] = inlink->sample_aspect_ratio.num ?
548  (double) inlink->sample_aspect_ratio.num / inlink->sample_aspect_ratio.den : 1;
549  scale->var_values[VAR_DAR] = scale->var_values[VAR_A] * scale->var_values[VAR_SAR];
550  scale->var_values[VAR_HSUB] = 1 << desc->log2_chroma_w;
551  scale->var_values[VAR_VSUB] = 1 << desc->log2_chroma_h;
552  scale->var_values[VAR_OHSUB] = 1 << out_desc->log2_chroma_w;
553  scale->var_values[VAR_OVSUB] = 1 << out_desc->log2_chroma_h;
554 
555  if (scale2ref) {
556  scale->var_values[VAR_S2R_MAIN_W] = main_link->w;
557  scale->var_values[VAR_S2R_MAIN_H] = main_link->h;
558  scale->var_values[VAR_S2R_MAIN_A] = (double) main_link->w / main_link->h;
559  scale->var_values[VAR_S2R_MAIN_SAR] = main_link->sample_aspect_ratio.num ?
560  (double) main_link->sample_aspect_ratio.num / main_link->sample_aspect_ratio.den : 1;
561  scale->var_values[VAR_S2R_MAIN_DAR] = scale->var_values[VAR_S2R_MDAR] =
562  scale->var_values[VAR_S2R_MAIN_A] * scale->var_values[VAR_S2R_MAIN_SAR];
563  scale->var_values[VAR_S2R_MAIN_HSUB] = 1 << main_desc->log2_chroma_w;
564  scale->var_values[VAR_S2R_MAIN_VSUB] = 1 << main_desc->log2_chroma_h;
565  }
566 
567  if (scale->uses_ref) {
568  const AVFilterLink *reflink = ctx->inputs[1];
569  const AVPixFmtDescriptor *ref_desc = av_pix_fmt_desc_get(reflink->format);
570  scale->var_values[VAR_REF_W] = scale->var_values[VAR_RW] = reflink->w;
571  scale->var_values[VAR_REF_H] = scale->var_values[VAR_RH] = reflink->h;
572  scale->var_values[VAR_REF_A] = (double) reflink->w / reflink->h;
573  scale->var_values[VAR_REF_SAR] = reflink->sample_aspect_ratio.num ?
574  (double) reflink->sample_aspect_ratio.num / reflink->sample_aspect_ratio.den : 1;
575  scale->var_values[VAR_REF_DAR] = scale->var_values[VAR_RDAR] =
576  scale->var_values[VAR_REF_A] * scale->var_values[VAR_REF_SAR];
577  scale->var_values[VAR_REF_HSUB] = 1 << ref_desc->log2_chroma_w;
578  scale->var_values[VAR_REF_VSUB] = 1 << ref_desc->log2_chroma_h;
579  }
580 
581  res = av_expr_eval(scale->w_pexpr, scale->var_values, NULL);
582  eval_w = scale->var_values[VAR_OUT_W] = scale->var_values[VAR_OW] = (int) res == 0 ? inlink->w : (int) res;
583 
584  res = av_expr_eval(scale->h_pexpr, scale->var_values, NULL);
585  if (isnan(res)) {
586  expr = scale->h_expr;
587  ret = AVERROR(EINVAL);
588  goto fail;
589  }
590  eval_h = scale->var_values[VAR_OUT_H] = scale->var_values[VAR_OH] = (int) res == 0 ? inlink->h : (int) res;
591 
592  res = av_expr_eval(scale->w_pexpr, scale->var_values, NULL);
593  if (isnan(res)) {
594  expr = scale->w_expr;
595  ret = AVERROR(EINVAL);
596  goto fail;
597  }
598  eval_w = scale->var_values[VAR_OUT_W] = scale->var_values[VAR_OW] = (int) res == 0 ? inlink->w : (int) res;
599 
600  scale->w = eval_w;
601  scale->h = eval_h;
602 
603  return 0;
604 
605 fail:
607  "Error when evaluating the expression '%s'.\n", expr);
608  return ret;
609 }
610 
611 static int config_props(AVFilterLink *outlink)
612 {
613  AVFilterContext *ctx = outlink->src;
614  AVFilterLink *inlink0 = outlink->src->inputs[0];
615  AVFilterLink *inlink = ctx->filter == &ff_vf_scale2ref ?
616  outlink->src->inputs[1] :
617  outlink->src->inputs[0];
618  ScaleContext *scale = ctx->priv;
619  uint8_t *flags_val = NULL;
620  int ret;
621 
622  if ((ret = scale_eval_dimensions(ctx)) < 0)
623  goto fail;
624 
625  outlink->w = scale->w;
626  outlink->h = scale->h;
627 
628  ret = ff_scale_adjust_dimensions(inlink, &outlink->w, &outlink->h,
629  scale->force_original_aspect_ratio,
630  scale->force_divisible_by);
631 
632  if (ret < 0)
633  goto fail;
634 
635  if (outlink->w > INT_MAX ||
636  outlink->h > INT_MAX ||
637  (outlink->h * inlink->w) > INT_MAX ||
638  (outlink->w * inlink->h) > INT_MAX)
639  av_log(ctx, AV_LOG_ERROR, "Rescaled value for width or height is too big.\n");
640 
641  /* TODO: make algorithm configurable */
642 
643  if (inlink0->sample_aspect_ratio.num){
644  outlink->sample_aspect_ratio = av_mul_q((AVRational){outlink->h * inlink0->w, outlink->w * inlink0->h}, inlink0->sample_aspect_ratio);
645  } else
646  outlink->sample_aspect_ratio = inlink0->sample_aspect_ratio;
647 
648  av_opt_get(scale->sws, "sws_flags", 0, &flags_val);
649  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",
650  inlink ->w, inlink ->h, av_get_pix_fmt_name( inlink->format),
651  av_color_space_name(inlink->colorspace), av_color_range_name(inlink->color_range),
652  inlink->sample_aspect_ratio.num, inlink->sample_aspect_ratio.den,
653  outlink->w, outlink->h, av_get_pix_fmt_name(outlink->format),
655  outlink->sample_aspect_ratio.num, outlink->sample_aspect_ratio.den,
656  flags_val);
657  av_freep(&flags_val);
658 
659  if (ctx->filter != &ff_vf_scale2ref) {
661  ret = ff_framesync_init(&scale->fs, ctx, ctx->nb_inputs);
662  if (ret < 0)
663  return ret;
664  scale->fs.on_event = do_scale;
665  scale->fs.in[0].time_base = ctx->inputs[0]->time_base;
666  scale->fs.in[0].sync = 1;
667  scale->fs.in[0].before = EXT_STOP;
668  scale->fs.in[0].after = EXT_STOP;
669  if (scale->uses_ref) {
670  av_assert0(ctx->nb_inputs == 2);
671  scale->fs.in[1].time_base = ctx->inputs[1]->time_base;
672  scale->fs.in[1].sync = 0;
673  scale->fs.in[1].before = EXT_NULL;
674  scale->fs.in[1].after = EXT_INFINITY;
675  }
676 
678  if (ret < 0)
679  return ret;
680  }
681 
682  return 0;
683 
684 fail:
685  return ret;
686 }
687 
688 static int config_props_ref(AVFilterLink *outlink)
689 {
690  AVFilterLink *inlink = outlink->src->inputs[1];
692  FilterLink *ol = ff_filter_link(outlink);
693 
694  outlink->w = inlink->w;
695  outlink->h = inlink->h;
696  outlink->sample_aspect_ratio = inlink->sample_aspect_ratio;
697  outlink->time_base = inlink->time_base;
698  ol->frame_rate = il->frame_rate;
699  outlink->colorspace = inlink->colorspace;
700  outlink->color_range = inlink->color_range;
701 
702  return 0;
703 }
704 
705 static int request_frame(AVFilterLink *outlink)
706 {
707  return ff_request_frame(outlink->src->inputs[0]);
708 }
709 
710 static int request_frame_ref(AVFilterLink *outlink)
711 {
712  return ff_request_frame(outlink->src->inputs[1]);
713 }
714 
715 /* Takes over ownership of *frame_in, passes ownership of *frame_out to caller */
716 static int scale_frame(AVFilterLink *link, AVFrame **frame_in,
717  AVFrame **frame_out)
718 {
720  AVFilterContext *ctx = link->dst;
721  ScaleContext *scale = ctx->priv;
722  AVFilterLink *outlink = ctx->outputs[0];
723  AVFrame *out, *in = *frame_in;
725  char buf[32];
726  int ret, flags_orig, frame_changed;
727 
728  *frame_in = NULL;
729 
730  frame_changed = in->width != link->w ||
731  in->height != link->h ||
732  in->format != link->format ||
735  in->colorspace != link->colorspace ||
736  in->color_range != link->color_range;
737 
738  if (scale->eval_mode == EVAL_MODE_FRAME || frame_changed) {
739  unsigned vars_w[VARS_NB] = { 0 }, vars_h[VARS_NB] = { 0 };
740 
741  av_expr_count_vars(scale->w_pexpr, vars_w, VARS_NB);
742  av_expr_count_vars(scale->h_pexpr, vars_h, VARS_NB);
743 
744  if (scale->eval_mode == EVAL_MODE_FRAME &&
745  !frame_changed &&
746  ctx->filter != &ff_vf_scale2ref &&
747  !(vars_w[VAR_N] || vars_w[VAR_T]
749  || vars_w[VAR_POS]
750 #endif
751  ) &&
752  !(vars_h[VAR_N] || vars_h[VAR_T]
754  || vars_h[VAR_POS]
755 #endif
756  ) &&
757  scale->w && scale->h)
758  goto scale;
759 
760  if (scale->eval_mode == EVAL_MODE_INIT) {
761  snprintf(buf, sizeof(buf) - 1, "%d", scale->w);
762  av_opt_set(scale, "w", buf, 0);
763  snprintf(buf, sizeof(buf) - 1, "%d", scale->h);
764  av_opt_set(scale, "h", buf, 0);
765 
766  ret = scale_parse_expr(ctx, NULL, &scale->w_pexpr, "width", scale->w_expr);
767  if (ret < 0)
768  goto err;
769 
770  ret = scale_parse_expr(ctx, NULL, &scale->h_pexpr, "height", scale->h_expr);
771  if (ret < 0)
772  goto err;
773  }
774 
775  if (ctx->filter == &ff_vf_scale2ref) {
776  scale->var_values[VAR_S2R_MAIN_N] = inl->frame_count_out;
777  scale->var_values[VAR_S2R_MAIN_T] = TS2T(in->pts, link->time_base);
778 #if FF_API_FRAME_PKT
780  scale->var_values[VAR_S2R_MAIN_POS] = in->pkt_pos == -1 ? NAN : in->pkt_pos;
782 #endif
783  } else {
784  scale->var_values[VAR_N] = inl->frame_count_out;
785  scale->var_values[VAR_T] = TS2T(in->pts, link->time_base);
786 #if FF_API_FRAME_PKT
788  scale->var_values[VAR_POS] = in->pkt_pos == -1 ? NAN : in->pkt_pos;
790 #endif
791  }
792 
793  link->dst->inputs[0]->format = in->format;
794  link->dst->inputs[0]->w = in->width;
795  link->dst->inputs[0]->h = in->height;
796  link->dst->inputs[0]->colorspace = in->colorspace;
797  link->dst->inputs[0]->color_range = in->color_range;
798 
799  link->dst->inputs[0]->sample_aspect_ratio.den = in->sample_aspect_ratio.den;
800  link->dst->inputs[0]->sample_aspect_ratio.num = in->sample_aspect_ratio.num;
801 
802  if ((ret = config_props(outlink)) < 0)
803  goto err;
804  }
805 
806 scale:
807  scale->hsub = desc->log2_chroma_w;
808  scale->vsub = desc->log2_chroma_h;
809 
810  out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
811  if (!out) {
812  ret = AVERROR(ENOMEM);
813  goto err;
814  }
815 
816  if (scale->in_color_matrix != -1)
817  in->colorspace = scale->in_color_matrix;
818  if (scale->in_range != AVCOL_RANGE_UNSPECIFIED)
819  in->color_range = scale->in_range;
820  in->chroma_location = scale->in_chroma_loc;
821 
822  flags_orig = in->flags;
823  if (scale->interlaced > 0)
825  else if (!scale->interlaced)
827 
829  out->width = outlink->w;
830  out->height = outlink->h;
831  out->color_range = outlink->color_range;
832  out->colorspace = outlink->colorspace;
833  if (scale->out_chroma_loc != AVCHROMA_LOC_UNSPECIFIED)
834  out->chroma_location = scale->out_chroma_loc;
835 
836  av_reduce(&out->sample_aspect_ratio.num, &out->sample_aspect_ratio.den,
837  (int64_t)in->sample_aspect_ratio.num * outlink->h * link->w,
838  (int64_t)in->sample_aspect_ratio.den * outlink->w * link->h,
839  INT_MAX);
840 
841  if (sws_is_noop(out, in)) {
842  av_frame_free(&out);
843  in->flags = flags_orig;
844  *frame_out = in;
845  return 0;
846  }
847 
848  if (out->format == AV_PIX_FMT_PAL8) {
849  out->format = AV_PIX_FMT_BGR8;
850  avpriv_set_systematic_pal2((uint32_t*) out->data[1], out->format);
851  }
852 
853  ret = sws_scale_frame(scale->sws, out, in);
854  av_frame_free(&in);
855  out->flags = flags_orig;
856  out->format = outlink->format; /* undo PAL8 handling */
857  if (ret < 0)
858  av_frame_free(&out);
859  *frame_out = out;
860  return ret;
861 
862 err:
863  av_frame_free(&in);
864  return ret;
865 }
866 
867 static int do_scale(FFFrameSync *fs)
868 {
869  AVFilterContext *ctx = fs->parent;
870  ScaleContext *scale = ctx->priv;
871  AVFilterLink *outlink = ctx->outputs[0];
872  AVFrame *out, *in = NULL, *ref = NULL;
873  int ret = 0, frame_changed;
874 
875  ret = ff_framesync_get_frame(fs, 0, &in, 1);
876  if (ret < 0)
877  goto err;
878 
879  if (scale->uses_ref) {
880  ret = ff_framesync_get_frame(fs, 1, &ref, 0);
881  if (ret < 0)
882  goto err;
883  }
884 
885  if (ref) {
886  AVFilterLink *reflink = ctx->inputs[1];
887  FilterLink *rl = ff_filter_link(reflink);
888 
889  frame_changed = ref->width != reflink->w ||
890  ref->height != reflink->h ||
891  ref->format != reflink->format ||
892  ref->sample_aspect_ratio.den != reflink->sample_aspect_ratio.den ||
893  ref->sample_aspect_ratio.num != reflink->sample_aspect_ratio.num ||
894  ref->colorspace != reflink->colorspace ||
895  ref->color_range != reflink->color_range;
896 
897  if (frame_changed) {
898  reflink->format = ref->format;
899  reflink->w = ref->width;
900  reflink->h = ref->height;
901  reflink->sample_aspect_ratio.num = ref->sample_aspect_ratio.num;
902  reflink->sample_aspect_ratio.den = ref->sample_aspect_ratio.den;
903  reflink->colorspace = ref->colorspace;
904  reflink->color_range = ref->color_range;
905 
906  ret = config_props(outlink);
907  if (ret < 0)
908  goto err;
909  }
910 
911  if (scale->eval_mode == EVAL_MODE_FRAME) {
912  scale->var_values[VAR_REF_N] = rl->frame_count_out;
913  scale->var_values[VAR_REF_T] = TS2T(ref->pts, reflink->time_base);
914 #if FF_API_FRAME_PKT
916  scale->var_values[VAR_REF_POS] = ref->pkt_pos == -1 ? NAN : ref->pkt_pos;
918 #endif
919  }
920  }
921 
922  ret = scale_frame(ctx->inputs[0], &in, &out);
923  if (ret < 0)
924  goto err;
925 
926  av_assert0(out);
927  out->pts = av_rescale_q(fs->pts, fs->time_base, outlink->time_base);
928  return ff_filter_frame(outlink, out);
929 
930 err:
931  av_frame_free(&in);
932  return ret;
933 }
934 
936 {
937  AVFilterContext *ctx = link->dst;
938  AVFilterLink *outlink = ctx->outputs[0];
939  AVFrame *out;
940  int ret;
941 
942  ret = scale_frame(link, &in, &out);
943  if (out)
944  return ff_filter_frame(outlink, out);
945 
946  return ret;
947 }
948 
950 {
952  ScaleContext *scale = link->dst->priv;
953  AVFilterLink *outlink = link->dst->outputs[1];
954  int frame_changed;
955 
956  frame_changed = in->width != link->w ||
957  in->height != link->h ||
958  in->format != link->format ||
961  in->colorspace != link->colorspace ||
962  in->color_range != link->color_range;
963 
964  if (frame_changed) {
965  link->format = in->format;
966  link->w = in->width;
967  link->h = in->height;
970  link->colorspace = in->colorspace;
972 
973  config_props_ref(outlink);
974  }
975 
976  if (scale->eval_mode == EVAL_MODE_FRAME) {
977  scale->var_values[VAR_N] = l->frame_count_out;
978  scale->var_values[VAR_T] = TS2T(in->pts, link->time_base);
979 #if FF_API_FRAME_PKT
981  scale->var_values[VAR_POS] = in->pkt_pos == -1 ? NAN : in->pkt_pos;
983 #endif
984  }
985 
986  return ff_filter_frame(outlink, in);
987 }
988 
989 static int process_command(AVFilterContext *ctx, const char *cmd, const char *args,
990  char *res, int res_len, int flags)
991 {
992  ScaleContext *scale = ctx->priv;
993  char *str_expr;
994  AVExpr **pexpr_ptr;
995  int ret, w, h;
996 
997  w = !strcmp(cmd, "width") || !strcmp(cmd, "w");
998  h = !strcmp(cmd, "height") || !strcmp(cmd, "h");
999 
1000  if (w || h) {
1001  str_expr = w ? scale->w_expr : scale->h_expr;
1002  pexpr_ptr = w ? &scale->w_pexpr : &scale->h_pexpr;
1003 
1004  ret = scale_parse_expr(ctx, str_expr, pexpr_ptr, cmd, args);
1005  } else
1006  ret = AVERROR(ENOSYS);
1007 
1008  if (ret < 0)
1009  av_log(ctx, AV_LOG_ERROR, "Failed to process command. Continuing with existing parameters.\n");
1010 
1011  return ret;
1012 }
1013 
1015 {
1016  ScaleContext *scale = ctx->priv;
1017  return ff_framesync_activate(&scale->fs);
1018 }
1019 
1020 static const AVClass *child_class_iterate(void **iter)
1021 {
1022  switch ((uintptr_t) *iter) {
1023  case 0:
1024  *iter = (void*)(uintptr_t) 1;
1025  return sws_get_class();
1026  case 1:
1027  *iter = (void*)(uintptr_t) 2;
1028  return &ff_framesync_class;
1029  }
1030 
1031  return NULL;
1032 }
1033 
1034 static void *child_next(void *obj, void *prev)
1035 {
1036  ScaleContext *s = obj;
1037  if (!prev)
1038  return s->sws;
1039  if (prev == s->sws)
1040  return &s->fs;
1041  return NULL;
1042 }
1043 
1044 #define OFFSET(x) offsetof(ScaleContext, x)
1045 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
1046 #define TFLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_RUNTIME_PARAM
1047 
1048 static const AVOption scale_options[] = {
1049  { "w", "Output video width", OFFSET(w_expr), AV_OPT_TYPE_STRING, .flags = TFLAGS },
1050  { "width", "Output video width", OFFSET(w_expr), AV_OPT_TYPE_STRING, .flags = TFLAGS },
1051  { "h", "Output video height", OFFSET(h_expr), AV_OPT_TYPE_STRING, .flags = TFLAGS },
1052  { "height","Output video height", OFFSET(h_expr), AV_OPT_TYPE_STRING, .flags = TFLAGS },
1053  { "flags", "Flags to pass to libswscale", OFFSET(flags_str), AV_OPT_TYPE_STRING, { .str = "" }, .flags = FLAGS },
1054  { "interl", "set interlacing", OFFSET(interlaced), AV_OPT_TYPE_BOOL, {.i64 = 0 }, -1, 1, FLAGS },
1055  { "size", "set video size", OFFSET(size_str), AV_OPT_TYPE_STRING, {.str = NULL}, 0, .flags = FLAGS },
1056  { "s", "set video size", OFFSET(size_str), AV_OPT_TYPE_STRING, {.str = NULL}, 0, .flags = FLAGS },
1057  { "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" },
1058  { "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"},
1059  { "auto", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = -1 }, 0, 0, FLAGS, .unit = "color" },
1060  { "bt601", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AVCOL_SPC_BT470BG }, 0, 0, FLAGS, .unit = "color" },
1061  { "bt470", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AVCOL_SPC_BT470BG }, 0, 0, FLAGS, .unit = "color" },
1062  { "smpte170m", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AVCOL_SPC_BT470BG }, 0, 0, FLAGS, .unit = "color" },
1063  { "bt709", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AVCOL_SPC_BT709 }, 0, 0, FLAGS, .unit = "color" },
1064  { "fcc", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AVCOL_SPC_FCC }, 0, 0, FLAGS, .unit = "color" },
1065  { "smpte240m", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AVCOL_SPC_SMPTE240M }, 0, 0, FLAGS, .unit = "color" },
1066  { "bt2020", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AVCOL_SPC_BT2020_NCL }, 0, 0, FLAGS, .unit = "color" },
1067  { "in_range", "set input color range", OFFSET( in_range), AV_OPT_TYPE_INT, {.i64 = AVCOL_RANGE_UNSPECIFIED }, 0, 2, FLAGS, .unit = "range" },
1068  { "out_range", "set output color range", OFFSET(out_range), AV_OPT_TYPE_INT, {.i64 = AVCOL_RANGE_UNSPECIFIED }, 0, 2, FLAGS, .unit = "range" },
1069  { "auto", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_UNSPECIFIED }, 0, 0, FLAGS, .unit = "range" },
1070  { "unknown", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_UNSPECIFIED }, 0, 0, FLAGS, .unit = "range" },
1071  { "full", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_JPEG}, 0, 0, FLAGS, .unit = "range" },
1072  { "limited",NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_MPEG}, 0, 0, FLAGS, .unit = "range" },
1073  { "jpeg", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_JPEG}, 0, 0, FLAGS, .unit = "range" },
1074  { "mpeg", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_MPEG}, 0, 0, FLAGS, .unit = "range" },
1075  { "tv", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_MPEG}, 0, 0, FLAGS, .unit = "range" },
1076  { "pc", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_JPEG}, 0, 0, FLAGS, .unit = "range" },
1077  { "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" },
1078  { "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" },
1079  {"auto", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCHROMA_LOC_UNSPECIFIED}, 0, 0, FLAGS, .unit = "chroma_loc"},
1080  {"unknown", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCHROMA_LOC_UNSPECIFIED}, 0, 0, FLAGS, .unit = "chroma_loc"},
1081  {"left", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCHROMA_LOC_LEFT}, 0, 0, FLAGS, .unit = "chroma_loc"},
1082  {"center", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCHROMA_LOC_CENTER}, 0, 0, FLAGS, .unit = "chroma_loc"},
1083  {"topleft", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCHROMA_LOC_TOPLEFT}, 0, 0, FLAGS, .unit = "chroma_loc"},
1084  {"top", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCHROMA_LOC_TOP}, 0, 0, FLAGS, .unit = "chroma_loc"},
1085  {"bottomleft", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCHROMA_LOC_BOTTOMLEFT}, 0, 0, FLAGS, .unit = "chroma_loc"},
1086  {"bottom", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCHROMA_LOC_BOTTOM}, 0, 0, FLAGS, .unit = "chroma_loc"},
1087  { "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 },
1088  { "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 },
1089  { "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 },
1090  { "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 },
1091  { "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" },
1092  { "disable", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 0 }, 0, 0, FLAGS, .unit = "force_oar" },
1093  { "decrease", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 1 }, 0, 0, FLAGS, .unit = "force_oar" },
1094  { "increase", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 2 }, 0, 0, FLAGS, .unit = "force_oar" },
1095  { "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 },
1096  { "param0", "Scaler param 0", OFFSET(param[0]), AV_OPT_TYPE_DOUBLE, { .dbl = DBL_MAX }, -DBL_MAX, DBL_MAX, FLAGS },
1097  { "param1", "Scaler param 1", OFFSET(param[1]), AV_OPT_TYPE_DOUBLE, { .dbl = DBL_MAX }, -DBL_MAX, DBL_MAX, FLAGS },
1098  { "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" },
1099  { "init", "eval expressions once during initialization", 0, AV_OPT_TYPE_CONST, {.i64=EVAL_MODE_INIT}, .flags = FLAGS, .unit = "eval" },
1100  { "frame", "eval expressions during initialization and per-frame", 0, AV_OPT_TYPE_CONST, {.i64=EVAL_MODE_FRAME}, .flags = FLAGS, .unit = "eval" },
1101  { NULL }
1102 };
1103 
1104 static const AVClass scale_class = {
1105  .class_name = "scale",
1106  .item_name = av_default_item_name,
1107  .option = scale_options,
1108  .version = LIBAVUTIL_VERSION_INT,
1109  .category = AV_CLASS_CATEGORY_FILTER,
1110  .child_class_iterate = child_class_iterate,
1112 };
1113 
1115  {
1116  .name = "default",
1117  .type = AVMEDIA_TYPE_VIDEO,
1118  },
1119 };
1120 
1122  {
1123  .name = "default",
1124  .type = AVMEDIA_TYPE_VIDEO,
1125  .config_props = config_props,
1126  },
1127 };
1128 
1130  .name = "scale",
1131  .description = NULL_IF_CONFIG_SMALL("Scale the input video size and/or convert the image format."),
1132  .preinit = preinit,
1133  .init = init,
1134  .uninit = uninit,
1135  .priv_size = sizeof(ScaleContext),
1136  .priv_class = &scale_class,
1140  .activate = activate,
1141  .process_command = process_command,
1143 };
1144 
1145 static const AVClass *scale2ref_child_class_iterate(void **iter)
1146 {
1147  const AVClass *c = *iter ? NULL : sws_get_class();
1148  *iter = (void*)(uintptr_t)c;
1149  return c;
1150 }
1151 
1152 static void *scale2ref_child_next(void *obj, void *prev)
1153 {
1154  ScaleContext *s = obj;
1155  if (!prev)
1156  return s->sws;
1157  return NULL;
1158 }
1159 
1160 static const AVClass scale2ref_class = {
1161  .class_name = "scale(2ref)",
1162  .item_name = av_default_item_name,
1163  .option = scale_options,
1164  .version = LIBAVUTIL_VERSION_INT,
1165  .category = AV_CLASS_CATEGORY_FILTER,
1166  .child_class_iterate = scale2ref_child_class_iterate,
1168 };
1169 
1171  {
1172  .name = "default",
1173  .type = AVMEDIA_TYPE_VIDEO,
1174  .filter_frame = filter_frame,
1175  },
1176  {
1177  .name = "ref",
1178  .type = AVMEDIA_TYPE_VIDEO,
1179  .filter_frame = filter_frame_ref,
1180  },
1181 };
1182 
1184  {
1185  .name = "default",
1186  .type = AVMEDIA_TYPE_VIDEO,
1187  .config_props = config_props,
1188  .request_frame= request_frame,
1189  },
1190  {
1191  .name = "ref",
1192  .type = AVMEDIA_TYPE_VIDEO,
1193  .config_props = config_props_ref,
1194  .request_frame= request_frame_ref,
1195  },
1196 };
1197 
1199  .name = "scale2ref",
1200  .description = NULL_IF_CONFIG_SMALL("Scale the input video size and/or convert the image format to the given reference."),
1201  .preinit = preinit,
1202  .init = init,
1203  .uninit = uninit,
1204  .priv_size = sizeof(ScaleContext),
1205  .priv_class = &scale2ref_class,
1209  .process_command = process_command,
1210 };
filter_frame_ref
static int filter_frame_ref(AVFilterLink *link, AVFrame *in)
Definition: vf_scale.c:949
ScaleContext::param
double param[2]
Definition: vf_scale.c:146
VAR_S2R_MAIN_SAR
@ VAR_S2R_MAIN_SAR
Definition: vf_scale.c:117
formats
formats
Definition: signature.h:47
ff_get_video_buffer
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.
Definition: video.c:116
ScaleContext::fs
FFFrameSync fs
Definition: vf_scale.c:136
VAR_S2R_MAIN_A
@ VAR_S2R_MAIN_A
Definition: vf_scale.c:116
VAR_HSUB
@ VAR_HSUB
Definition: vf_scale.c:95
FF_ENABLE_DEPRECATION_WARNINGS
#define FF_ENABLE_DEPRECATION_WARNINGS
Definition: internal.h:73
config_props_ref
static int config_props_ref(AVFilterLink *outlink)
Definition: vf_scale.c:688
ff_framesync_configure
int ff_framesync_configure(FFFrameSync *fs)
Configure a frame sync structure.
Definition: framesync.c:137
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:215
AVFrame::color_range
enum AVColorRange color_range
MPEG vs JPEG YUV range.
Definition: frame.h:668
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:71
TFLAGS
#define TFLAGS
Definition: vf_scale.c:1046
check_exprs
static int check_exprs(AVFilterContext *ctx)
Definition: vf_scale.c:185
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
opt.h
var_name
var_name
Definition: noise.c:47
VAR_REF_POS
@ VAR_REF_POS
Definition: vf_scale.c:113
ff_framesync_uninit
void ff_framesync_uninit(FFFrameSync *fs)
Free all memory currently allocated.
Definition: framesync.c:301
out
FILE * out
Definition: movenc.c:55
ScaleContext
Definition: vf_scale.c:133
ff_filter_frame
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1061
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:3170
AVCHROMA_LOC_BOTTOM
@ AVCHROMA_LOC_BOTTOM
Definition: pixfmt.h:743
ScaleContext::force_divisible_by
int force_divisible_by
Definition: vf_scale.c:175
VAR_REF_N
@ VAR_REF_N
Definition: vf_scale.c:111
ff_framesync_get_frame
int ff_framesync_get_frame(FFFrameSync *fs, unsigned in, AVFrame **rframe, unsigned get)
Get the current frame in an input.
Definition: framesync.c:269
avfilter_vf_scale2ref_outputs
static const AVFilterPad avfilter_vf_scale2ref_outputs[]
Definition: vf_scale.c:1183
FLAGS
#define FLAGS
Definition: vf_scale.c:1045
int64_t
long long int64_t
Definition: coverity.c:34
ScaleContext::flags_str
char * flags_str
Definition: vf_scale.c:159
inlink
The exact code depends on how similar the blocks are and how related they are to the and needs to apply these operations to the correct inlink or outlink if there are several Macros are available to factor that when no extra processing is inlink
Definition: filter_design.txt:212
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:162
AVFrame::colorspace
enum AVColorSpace colorspace
YUV colorspace type.
Definition: frame.h:679
FILTER_INPUTS
#define FILTER_INPUTS(array)
Definition: filters.h:262
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:389
pixdesc.h
AVFrame::pts
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:501
AVFrame::width
int width
Definition: frame.h:461
w
uint8_t w
Definition: llviddspenc.c:38
AVCOL_RANGE_JPEG
@ AVCOL_RANGE_JPEG
Full range content.
Definition: pixfmt.h:717
VAR_A
@ VAR_A
Definition: vf_scale.c:92
request_frame_ref
static int request_frame_ref(AVFilterLink *outlink)
Definition: vf_scale.c:710
AVOption
AVOption.
Definition: opt.h:429
AVCOL_SPC_NB
@ AVCOL_SPC_NB
Not part of ABI.
Definition: pixfmt.h:660
scale_parse_expr
static int scale_parse_expr(AVFilterContext *ctx, char *str_expr, AVExpr **pexpr_ptr, const char *var, const char *args)
Definition: vf_scale.c:277
scale2ref_class
static const AVClass scale2ref_class
Definition: vf_scale.c:1160
request_frame
static int request_frame(AVFilterLink *outlink)
Definition: vf_scale.c:705
av_pix_fmt_desc_next
const AVPixFmtDescriptor * av_pix_fmt_desc_next(const AVPixFmtDescriptor *prev)
Iterate over all pixel format descriptors known to libavutil.
Definition: pixdesc.c:3177
VAR_REF_T
@ VAR_REF_T
Definition: vf_scale.c:112
ff_request_frame
int ff_request_frame(AVFilterLink *link)
Request an input frame from the filter at the other end of the link.
Definition: avfilter.c:475
VAR_S2R_MAIN_HSUB
@ VAR_S2R_MAIN_HSUB
Definition: vf_scale.c:119
ScaleContext::var_values
double var_values[VARS_NB]
Definition: vf_scale.c:157
ScaleContext::out_range
int out_range
Definition: vf_scale.c:165
VAR_S2R_MDAR
@ VAR_S2R_MDAR
Definition: vf_scale.c:118
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:225
float.h
EVAL_MODE_FRAME
@ EVAL_MODE_FRAME
Definition: vf_scale.c:129
VAR_S2R_MAIN_H
@ VAR_S2R_MAIN_H
Definition: vf_scale.c:115
AVFrame::flags
int flags
Frame flags, a combination of AV_FRAME_FLAGS.
Definition: frame.h:661
AVFilter::name
const char * name
Filter name.
Definition: avfilter.h:205
FFFrameSync
Frame sync structure.
Definition: framesync.h:168
EXT_INFINITY
@ EXT_INFINITY
Extend the frame to infinity.
Definition: framesync.h:75
ScaleContext::in_h_chr_pos
int in_h_chr_pos
Definition: vf_scale.c:171
VAR_OUT_H
@ VAR_OUT_H
Definition: vf_scale.c:91
video.h
ff_make_formats_list_singleton
AVFilterFormats * ff_make_formats_list_singleton(int fmt)
Equivalent to ff_make_format_list({const int[]}{ fmt, -1 })
Definition: formats.c:529
ScaleContext::out_chroma_loc
int out_chroma_loc
Definition: vf_scale.c:168
AVFilterFormats
A list of supported formats for one end of a filter link.
Definition: formats.h:64
formats.h
av_expr_parse
int av_expr_parse(AVExpr **expr, const char *s, const char *const *const_names, const char *const *func1_names, double(*const *funcs1)(void *, double), const char *const *func2_names, double(*const *funcs2)(void *, double, double), int log_offset, void *log_ctx)
Parse an expression.
Definition: eval.c:710
VAR_S2R_MAIN_POS
@ VAR_S2R_MAIN_POS
Definition: vf_scale.c:123
AVFrame::chroma_location
enum AVChromaLocation chroma_location
Definition: frame.h:681
AVCOL_SPC_BT470BG
@ AVCOL_SPC_BT470BG
also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM / IEC 61966-2-4 xvYCC601
Definition: pixfmt.h:646
EXT_STOP
@ EXT_STOP
Completely stop all streams with this one.
Definition: framesync.h:65
ff_append_inpad
int ff_append_inpad(AVFilterContext *f, AVFilterPad *p)
Append a new input/output pad to the filter's list of such pads.
Definition: avfilter.c:127
av_color_space_name
const char * av_color_space_name(enum AVColorSpace space)
Definition: pixdesc.c:3546
VAR_DAR
@ VAR_DAR
Definition: vf_scale.c:94
avfilter_vf_scale_inputs
static const AVFilterPad avfilter_vf_scale_inputs[]
Definition: vf_scale.c:1114
fail
#define fail()
Definition: checkasm.h:193
VARS_NB
@ VARS_NB
Definition: vf_scale.c:124
VAR_REF_A
@ VAR_REF_A
Definition: vf_scale.c:106
ScaleContext::eval_mode
int eval_mode
expression evaluation mode
Definition: vf_scale.c:177
EXT_NULL
@ EXT_NULL
Ignore this stream and continue processing the other ones.
Definition: framesync.h:70
VAR_IN_H
@ VAR_IN_H
Definition: vf_scale.c:89
EVAL_MODE_NB
@ EVAL_MODE_NB
Definition: vf_scale.c:130
ScaleContext::in_chroma_loc
int in_chroma_loc
Definition: vf_scale.c:167
sws_get_class
const AVClass * sws_get_class(void)
Get the AVClass for SwsContext.
Definition: options.c:99
av_opt_set
int av_opt_set(void *obj, const char *name, const char *val, int search_flags)
Definition: opt.c:835
VAR_REF_W
@ VAR_REF_W
Definition: vf_scale.c:104
AVFILTER_FLAG_DYNAMIC_INPUTS
#define AVFILTER_FLAG_DYNAMIC_INPUTS
The number of the filter inputs is not determined just by AVFilter.inputs.
Definition: avfilter.h:141
av_reduce
int av_reduce(int *dst_num, int *dst_den, int64_t num, int64_t den, int64_t max)
Reduce a fraction.
Definition: rational.c:35
av_expr_free
void av_expr_free(AVExpr *e)
Free a parsed expression previously created with av_expr_parse().
Definition: eval.c:358
AVRational::num
int num
Numerator.
Definition: rational.h:59
OFFSET
#define OFFSET(x)
Definition: vf_scale.c:1044
preinit
static av_cold int preinit(AVFilterContext *ctx)
Definition: vf_scale.c:330
AVFilterPad
A filter pad used for either input or output.
Definition: filters.h:38
activate
static int activate(AVFilterContext *ctx)
Definition: vf_scale.c:1014
AV_PIX_FMT_BGR8
@ AV_PIX_FMT_BGR8
packed RGB 3:3:2, 8bpp, (msb)2B 3G 3R(lsb)
Definition: pixfmt.h:90
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:209
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
av_cold
#define av_cold
Definition: attributes.h:90
VAR_REF_H
@ VAR_REF_H
Definition: vf_scale.c:105
scale2ref_child_next
static void * scale2ref_child_next(void *obj, void *prev)
Definition: vf_scale.c:1152
s
#define s(width, name)
Definition: cbs_vp9.c:198
VAR_OH
@ VAR_OH
Definition: vf_scale.c:91
AVCHROMA_LOC_TOP
@ AVCHROMA_LOC_TOP
Definition: pixfmt.h:741
VAR_S2R_MAIN_W
@ VAR_S2R_MAIN_W
Definition: vf_scale.c:114
ScaleContext::slice_y
int slice_y
top of current output slice
Definition: vf_scale.c:149
pix_fmt
static enum AVPixelFormat pix_fmt
Definition: demux_decode.c:41
AV_OPT_TYPE_DOUBLE
@ AV_OPT_TYPE_DOUBLE
Underlying C type is double.
Definition: opt.h:267
av_expr_count_vars
int av_expr_count_vars(AVExpr *e, unsigned *counter, int size)
Track the presence of variables and their number of occurrences in a parsed expression.
Definition: eval.c:782
query_formats
static int query_formats(const AVFilterContext *ctx, AVFilterFormatsConfig **cfg_in, AVFilterFormatsConfig **cfg_out)
Definition: vf_scale.c:447
ff_formats_ref
int ff_formats_ref(AVFilterFormats *f, AVFilterFormats **ref)
Add *ref as a new reference to formats.
Definition: formats.c:678
init
static av_cold int init(AVFilterContext *ctx)
Definition: vf_scale.c:348
VAR_OVSUB
@ VAR_OVSUB
Definition: vf_scale.c:98
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:40
filters.h
ScaleContext::uses_ref
int uses_ref
Definition: vf_scale.c:151
sws_test_colorspace
int sws_test_colorspace(enum AVColorSpace colorspace, int output)
Test if a given color space is supported.
Definition: utils.c:2716
ctx
AVFormatContext * ctx
Definition: movenc.c:49
process_command
static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, char *res, int res_len, int flags)
Definition: vf_scale.c:989
av_expr_eval
double av_expr_eval(AVExpr *e, const double *const_values, void *opaque)
Evaluate a previously parsed expression.
Definition: eval.c:792
av_rescale_q
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
Definition: mathematics.c:142
AVExpr
Definition: eval.c:158
AVPixFmtDescriptor::log2_chroma_w
uint8_t log2_chroma_w
Amount to shift the luma width right to find the chroma width.
Definition: pixdesc.h:80
ScaleContext::w_pexpr
AVExpr * w_pexpr
Definition: vf_scale.c:155
FILTER_OUTPUTS
#define FILTER_OUTPUTS(array)
Definition: filters.h:263
avpriv_set_systematic_pal2
int avpriv_set_systematic_pal2(uint32_t pal[256], enum AVPixelFormat pix_fmt)
Definition: imgutils.c:178
NAN
#define NAN
Definition: mathematics.h:115
link
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a link
Definition: filter_design.txt:23
ScaleContext::out_h_chr_pos
int out_h_chr_pos
Definition: vf_scale.c:169
av_color_range_name
const char * av_color_range_name(enum AVColorRange range)
Definition: pixdesc.c:3486
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
VAR_REF_DAR
@ VAR_REF_DAR
Definition: vf_scale.c:108
ff_framesync_class
const AVClass ff_framesync_class
Definition: framesync.c:54
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:75
NULL
#define NULL
Definition: coverity.c:32
ScaleContext::out_v_chr_pos
int out_v_chr_pos
Definition: vf_scale.c:170
av_frame_copy_props
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
Definition: frame.c:725
VAR_POS
@ VAR_POS
Definition: noise.c:56
VAR_T
@ VAR_T
Definition: vf_scale.c:100
fs
#define fs(width, name, subs,...)
Definition: cbs_vp9.c:200
AVCHROMA_LOC_LEFT
@ AVCHROMA_LOC_LEFT
MPEG-2/4 4:2:0, H.264 default for 4:2:0.
Definition: pixfmt.h:738
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
AVCHROMA_LOC_TOPLEFT
@ AVCHROMA_LOC_TOPLEFT
ITU-R 601, SMPTE 274M 296M S314M(DV 4:1:1), mpeg2 4:2:2.
Definition: pixfmt.h:740
sws_is_noop
int sws_is_noop(const AVFrame *dst, const AVFrame *src)
Check if a given conversion is a noop.
Definition: utils.c:2779
isnan
#define isnan(x)
Definition: libm.h:340
scale2ref_child_class_iterate
static const AVClass * scale2ref_child_class_iterate(void **iter)
Definition: vf_scale.c:1145
ScaleContext::in_range
int in_range
Definition: vf_scale.c:164
AVFilterContext::inputs
AVFilterLink ** inputs
array of pointers to input links
Definition: avfilter.h:465
VAR_IN_W
@ VAR_IN_W
Definition: vf_scale.c:88
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:237
ff_add_format
int ff_add_format(AVFilterFormats **avff, int64_t fmt)
Add fmt to the list of media formats contained in *avff.
Definition: formats.c:504
parseutils.h
sws_test_format
int sws_test_format(enum AVPixelFormat format, int output)
Test if a given pixel format is supported.
Definition: utils.c:2711
ScaleContext::h_pexpr
AVExpr * h_pexpr
Definition: vf_scale.c:156
double
double
Definition: af_crystalizer.c:132
ff_all_color_spaces
AVFilterFormats * ff_all_color_spaces(void)
Construct an AVFilterFormats representing all possible color spaces.
Definition: formats.c:630
ff_vf_scale2ref
const AVFilter ff_vf_scale2ref
Definition: vf_scale.c:181
AVCOL_RANGE_UNSPECIFIED
@ AVCOL_RANGE_UNSPECIFIED
Definition: pixfmt.h:683
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
AVFilterFormatsConfig
Lists of formats / etc.
Definition: avfilter.h:111
ScaleContext::out_color_matrix
int out_color_matrix
Definition: vf_scale.c:162
ff_filter_link
static FilterLink * ff_filter_link(AVFilterLink *link)
Definition: filters.h:197
AV_CLASS_CATEGORY_FILTER
@ AV_CLASS_CATEGORY_FILTER
Definition: log.h:36
VAR_IW
@ VAR_IW
Definition: vf_scale.c:88
ScaleContext::sws
SwsContext * sws
Definition: vf_scale.c:135
eval.h
VAR_IH
@ VAR_IH
Definition: vf_scale.c:89
VAR_REF_SAR
@ VAR_REF_SAR
Definition: vf_scale.c:107
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:94
sws_alloc_context
SwsContext * sws_alloc_context(void)
Allocate an empty SwsContext and set its fields to default values.
Definition: utils.c:1227
AVClass::child_next
void *(* child_next)(void *obj, void *prev)
Return next AVOptions-enabled child or NULL.
Definition: log.h:149
child_class_iterate
static const AVClass * child_class_iterate(void **iter)
Definition: vf_scale.c:1020
ScaleContext::w
int w
New dimensions.
Definition: vf_scale.c:144
AVFrame::time_base
AVRational time_base
Time base for the timestamps in this frame.
Definition: frame.h:516
scale_frame
static int scale_frame(AVFilterLink *link, AVFrame **frame_in, AVFrame **frame_out)
Definition: vf_scale.c:716
VAR_RH
@ VAR_RH
Definition: vf_scale.c:105
TS2T
#define TS2T(ts, tb)
Definition: filters.h:278
AVCHROMA_LOC_UNSPECIFIED
@ AVCHROMA_LOC_UNSPECIFIED
Definition: pixfmt.h:737
AVFrame::pkt_pos
attribute_deprecated int64_t pkt_pos
reordered pos from the last AVPacket that has been input into the decoder
Definition: frame.h:699
AVFrame::format
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames,...
Definition: frame.h:476
scale_eval.h
VAR_RW
@ VAR_RW
Definition: vf_scale.c:104
FF_API_FRAME_PKT
#define FF_API_FRAME_PKT
Definition: version.h:109
ScaleContext::hsub
int hsub
Definition: vf_scale.c:148
VAR_OUT_W
@ VAR_OUT_W
Definition: vf_scale.c:90
imgutils_internal.h
ff_all_color_ranges
AVFilterFormats * ff_all_color_ranges(void)
Construct an AVFilterFormats representing all possible color ranges.
Definition: formats.c:646
av_pix_fmt_desc_get_id
enum AVPixelFormat av_pix_fmt_desc_get_id(const AVPixFmtDescriptor *desc)
Definition: pixdesc.c:3189
filter_frame
static int filter_frame(AVFilterLink *link, AVFrame *in)
Definition: vf_scale.c:935
av_parse_video_size
int av_parse_video_size(int *width_ptr, int *height_ptr, const char *str)
Parse str and put in width_ptr and height_ptr the detected values.
Definition: parseutils.c:150
AVCOL_SPC_SMPTE240M
@ AVCOL_SPC_SMPTE240M
derived from 170M primaries and D65 white point, 170M is derived from BT470 System M's primaries
Definition: pixfmt.h:648
ScaleContext::vsub
int vsub
chroma subsampling
Definition: vf_scale.c:148
config_props
static int config_props(AVFilterLink *outlink)
Definition: vf_scale.c:611
interlaced
uint8_t interlaced
Definition: mxfenc.c:2270
VAR_SAR
@ VAR_SAR
Definition: vf_scale.c:93
VAR_RDAR
@ VAR_RDAR
Definition: vf_scale.c:108
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
AVCOL_SPC_BT2020_NCL
@ AVCOL_SPC_BT2020_NCL
ITU-R BT2020 non-constant luminance system.
Definition: pixfmt.h:651
VAR_S2R_MAIN_N
@ VAR_S2R_MAIN_N
Definition: vf_scale.c:121
internal.h
ff_filter_get_nb_threads
int ff_filter_get_nb_threads(AVFilterContext *ctx)
Get number of threads for current filter instance.
Definition: avfilter.c:840
EvalMode
EvalMode
Definition: af_volume.h:39
FILTER_QUERY_FUNC2
#define FILTER_QUERY_FUNC2(func)
Definition: filters.h:239
AVFilterPad::name
const char * name
Pad name.
Definition: filters.h:44
AVCOL_SPC_UNSPECIFIED
@ AVCOL_SPC_UNSPECIFIED
Definition: pixfmt.h:643
ScaleContext::h_expr
char * h_expr
height expression string
Definition: vf_scale.c:154
AV_FRAME_FLAG_INTERLACED
#define AV_FRAME_FLAG_INTERLACED
A flag to mark frames whose content is interlaced.
Definition: frame.h:648
AVCOL_RANGE_MPEG
@ AVCOL_RANGE_MPEG
Narrow or limited range content.
Definition: pixfmt.h:700
avfilter_vf_scale_outputs
static const AVFilterPad avfilter_vf_scale_outputs[]
Definition: vf_scale.c:1121
AVFilter
Filter definition.
Definition: avfilter.h:201
AV_PIX_FMT_PAL8
@ AV_PIX_FMT_PAL8
8 bits with AV_PIX_FMT_RGB32 palette
Definition: pixfmt.h:84
ret
ret
Definition: filter_design.txt:187
pixfmt.h
FFSWAP
#define FFSWAP(type, a, b)
Definition: macros.h:52
AVClass::class_name
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:80
ScaleContext::in_color_matrix
int in_color_matrix
Definition: vf_scale.c:161
VAR_REF_HSUB
@ VAR_REF_HSUB
Definition: vf_scale.c:109
child_next
static void * child_next(void *obj, void *prev)
Definition: vf_scale.c:1034
ff_framesync_init
int ff_framesync_init(FFFrameSync *fs, AVFilterContext *parent, unsigned nb_in)
Initialize a frame sync structure.
Definition: framesync.c:86
AVFrame::sample_aspect_ratio
AVRational sample_aspect_ratio
Sample aspect ratio for the video frame, 0/1 if unknown/unspecified.
Definition: frame.h:496
ff_scale_adjust_dimensions
int ff_scale_adjust_dimensions(AVFilterLink *inlink, int *ret_w, int *ret_h, int force_original_aspect_ratio, int force_divisible_by)
Transform evaluated width and height obtained from ff_scale_eval_dimensions into actual target width ...
Definition: scale_eval.c:113
VAR_S2R_MAIN_T
@ VAR_S2R_MAIN_T
Definition: vf_scale.c:122
scale_eval_dimensions
static int scale_eval_dimensions(AVFilterContext *ctx)
Definition: vf_scale.c:522
var_names
static const char *const var_names[]
Definition: vf_scale.c:46
AVFrame::height
int height
Definition: frame.h:461
VAR_S2R_MAIN_DAR
@ VAR_S2R_MAIN_DAR
Definition: vf_scale.c:118
scale_options
static const AVOption scale_options[]
Definition: vf_scale.c:1048
framesync.h
do_scale
static int do_scale(FFFrameSync *fs)
Definition: vf_scale.c:867
AVCHROMA_LOC_CENTER
@ AVCHROMA_LOC_CENTER
MPEG-1 4:2:0, JPEG 4:2:0, H.263 4:2:0.
Definition: pixfmt.h:739
AVRational::den
int den
Denominator.
Definition: rational.h:60
AVCOL_SPC_FCC
@ AVCOL_SPC_FCC
FCC Title 47 Code of Federal Regulations 73.682 (a)(20)
Definition: pixfmt.h:645
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition: opt.h:259
avfilter.h
uninit
static av_cold void uninit(AVFilterContext *ctx)
Definition: vf_scale.c:437
ScaleContext::force_original_aspect_ratio
int force_original_aspect_ratio
Definition: vf_scale.c:174
ref
static int ref[MAX_W *MAX_W]
Definition: jpeg2000dwt.c:117
avfilter_vf_scale2ref_inputs
static const AVFilterPad avfilter_vf_scale2ref_inputs[]
Definition: vf_scale.c:1170
av_mul_q
AVRational av_mul_q(AVRational b, AVRational c)
Multiply two rationals.
Definition: rational.c:80
AVFilterContext
An instance of a filter.
Definition: avfilter.h:457
VAR_OW
@ VAR_OW
Definition: vf_scale.c:90
FF_DISABLE_DEPRECATION_WARNINGS
#define FF_DISABLE_DEPRECATION_WARNINGS
Definition: internal.h:72
av_strdup
char * av_strdup(const char *s)
Duplicate a string.
Definition: mem.c:272
desc
const char * desc
Definition: libsvtav1.c:79
VAR_VSUB
@ VAR_VSUB
Definition: vf_scale.c:96
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
mem.h
AVPixFmtDescriptor
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:69
ScaleContext::interlaced
int interlaced
Definition: vf_scale.c:150
av_free
#define av_free(p)
Definition: tableprint_vlc.h:33
scale
static void scale(int *out, const int *in, const int w, const int h, const int shift)
Definition: intra.c:291
VAR_N
@ VAR_N
Definition: vf_scale.c:99
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Underlying C type is int.
Definition: opt.h:327
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
scale_class
static const AVClass scale_class
Definition: vf_scale.c:1104
ScaleContext::w_expr
char * w_expr
width expression string
Definition: vf_scale.c:153
sws_free_context
void sws_free_context(SwsContext **ctx)
Free the context and everything associated with it, and write NULL to the provided pointer.
Definition: utils.c:2526
EVAL_MODE_INIT
@ EVAL_MODE_INIT
Definition: vf_scale.c:128
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:482
AVCHROMA_LOC_NB
@ AVCHROMA_LOC_NB
Not part of ABI.
Definition: pixfmt.h:744
av_opt_get
int av_opt_get(void *obj, const char *name, int search_flags, uint8_t **out_val)
Definition: opt.c:1215
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
VAR_REF_VSUB
@ VAR_REF_VSUB
Definition: vf_scale.c:110
sws_scale_frame
int sws_scale_frame(SwsContext *sws, AVFrame *dst, const AVFrame *src)
Scale source data from src and write the output to dst.
Definition: swscale.c:1347
h
h
Definition: vp9dsp_template.c:2070
ff_framesync_activate
int ff_framesync_activate(FFFrameSync *fs)
Examine the frames in the filter's input and try to produce output.
Definition: framesync.c:352
AV_OPT_TYPE_STRING
@ AV_OPT_TYPE_STRING
Underlying C type is a uint8_t* that is either NULL or points to a C string allocated with the av_mal...
Definition: opt.h:276
VAR_OHSUB
@ VAR_OHSUB
Definition: vf_scale.c:97
AVCOL_SPC_BT709
@ AVCOL_SPC_BT709
also ITU-R BT1361 / IEC 61966-2-4 xvYCC709 / derived in SMPTE RP 177 Annex B
Definition: pixfmt.h:642
SwsContext
Main external API structure.
Definition: swscale.h:174
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
Definition: opt.h:299
ff_vf_scale
const AVFilter ff_vf_scale
Definition: vf_scale.c:1129
snprintf
#define snprintf
Definition: snprintf.h:34
ScaleContext::size_str
char * size_str
Definition: vf_scale.c:145
VAR_S2R_MAIN_VSUB
@ VAR_S2R_MAIN_VSUB
Definition: vf_scale.c:120
AVCHROMA_LOC_BOTTOMLEFT
@ AVCHROMA_LOC_BOTTOMLEFT
Definition: pixfmt.h:742
AVPixFmtDescriptor::log2_chroma_h
uint8_t log2_chroma_h
Amount to shift the luma height right to find the chroma height.
Definition: pixdesc.h:89
ff_framesync_preinit
void ff_framesync_preinit(FFFrameSync *fs)
Pre-initialize a frame sync structure.
Definition: framesync.c:78
swscale.h
ScaleContext::h
int h
Definition: vf_scale.c:144
av_x_if_null
static void * av_x_if_null(const void *p, const void *x)
Return x default pointer in case p is NULL.
Definition: avutil.h:312
av_get_pix_fmt_name
const char * av_get_pix_fmt_name(enum AVPixelFormat pix_fmt)
Return the short name for a pixel format, NULL in case pix_fmt is unknown.
Definition: pixdesc.c:3090
ScaleContext::in_v_chr_pos
int in_v_chr_pos
Definition: vf_scale.c:172