FFmpeg  4.3.7
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 <stdio.h>
27 #include <string.h>
28 
29 #include "avfilter.h"
30 #include "formats.h"
31 #include "internal.h"
32 #include "scale_eval.h"
33 #include "video.h"
34 #include "libavutil/avstring.h"
35 #include "libavutil/eval.h"
36 #include "libavutil/internal.h"
37 #include "libavutil/mathematics.h"
38 #include "libavutil/opt.h"
39 #include "libavutil/parseutils.h"
40 #include "libavutil/pixdesc.h"
41 #include "libavutil/imgutils.h"
42 #include "libavutil/avassert.h"
43 #include "libswscale/swscale.h"
44 
45 static const char *const var_names[] = {
46  "in_w", "iw",
47  "in_h", "ih",
48  "out_w", "ow",
49  "out_h", "oh",
50  "a",
51  "sar",
52  "dar",
53  "hsub",
54  "vsub",
55  "ohsub",
56  "ovsub",
57  "n",
58  "t",
59  "pos",
60  "main_w",
61  "main_h",
62  "main_a",
63  "main_sar",
64  "main_dar", "mdar",
65  "main_hsub",
66  "main_vsub",
67  "main_n",
68  "main_t",
69  "main_pos",
70  NULL
71 };
72 
73 enum var_name {
99 };
100 
101 enum EvalMode {
105 };
106 
107 typedef struct ScaleContext {
108  const AVClass *class;
109  struct SwsContext *sws; ///< software scaler context
110  struct SwsContext *isws[2]; ///< software scaler context for interlaced material
112 
113  /**
114  * New dimensions. Special values are:
115  * 0 = original width/height
116  * -1 = keep original aspect
117  * -N = try to keep aspect but make sure it is divisible by N
118  */
119  int w, h;
120  char *size_str;
121  unsigned int flags; ///sws flags
122  double param[2]; // sws params
123 
124  int hsub, vsub; ///< chroma subsampling
125  int slice_y; ///< top of current output slice
126  int input_is_pal; ///< set to 1 if the input format is paletted
127  int output_is_pal; ///< set to 1 if the output format is paletted
129 
130  char *w_expr; ///< width expression string
131  char *h_expr; ///< height expression string
135 
136  char *flags_str;
137 
140 
141  int in_range;
143 
148 
151 
153 
154  int eval_mode; ///< expression evaluation mode
155 
156 } ScaleContext;
157 
159 
160 static int config_props(AVFilterLink *outlink);
161 
163 {
164  ScaleContext *scale = ctx->priv;
165  unsigned vars_w[VARS_NB] = { 0 }, vars_h[VARS_NB] = { 0 };
166 
167  if (!scale->w_pexpr && !scale->h_pexpr)
168  return AVERROR(EINVAL);
169 
170  if (scale->w_pexpr)
171  av_expr_count_vars(scale->w_pexpr, vars_w, VARS_NB);
172  if (scale->h_pexpr)
173  av_expr_count_vars(scale->h_pexpr, vars_h, VARS_NB);
174 
175  if (vars_w[VAR_OUT_W] || vars_w[VAR_OW]) {
176  av_log(ctx, AV_LOG_ERROR, "Width expression cannot be self-referencing: '%s'.\n", scale->w_expr);
177  return AVERROR(EINVAL);
178  }
179 
180  if (vars_h[VAR_OUT_H] || vars_h[VAR_OH]) {
181  av_log(ctx, AV_LOG_ERROR, "Height expression cannot be self-referencing: '%s'.\n", scale->h_expr);
182  return AVERROR(EINVAL);
183  }
184 
185  if ((vars_w[VAR_OUT_H] || vars_w[VAR_OH]) &&
186  (vars_h[VAR_OUT_W] || vars_h[VAR_OW])) {
187  av_log(ctx, AV_LOG_WARNING, "Circular references detected for width '%s' and height '%s' - possibly invalid.\n", scale->w_expr, scale->h_expr);
188  }
189 
190  if (ctx->filter != &ff_vf_scale2ref &&
191  (vars_w[VAR_S2R_MAIN_W] || vars_h[VAR_S2R_MAIN_W] ||
192  vars_w[VAR_S2R_MAIN_H] || vars_h[VAR_S2R_MAIN_H] ||
193  vars_w[VAR_S2R_MAIN_A] || vars_h[VAR_S2R_MAIN_A] ||
194  vars_w[VAR_S2R_MAIN_SAR] || vars_h[VAR_S2R_MAIN_SAR] ||
195  vars_w[VAR_S2R_MAIN_DAR] || vars_h[VAR_S2R_MAIN_DAR] ||
196  vars_w[VAR_S2R_MDAR] || vars_h[VAR_S2R_MDAR] ||
197  vars_w[VAR_S2R_MAIN_HSUB] || vars_h[VAR_S2R_MAIN_HSUB] ||
198  vars_w[VAR_S2R_MAIN_VSUB] || vars_h[VAR_S2R_MAIN_VSUB] ||
199  vars_w[VAR_S2R_MAIN_N] || vars_h[VAR_S2R_MAIN_N] ||
200  vars_w[VAR_S2R_MAIN_T] || vars_h[VAR_S2R_MAIN_T] ||
201  vars_w[VAR_S2R_MAIN_POS] || vars_h[VAR_S2R_MAIN_POS]) ) {
202  av_log(ctx, AV_LOG_ERROR, "Expressions with scale2ref variables are not valid in scale filter.\n");
203  return AVERROR(EINVAL);
204  }
205 
206  if (scale->eval_mode == EVAL_MODE_INIT &&
207  (vars_w[VAR_N] || vars_h[VAR_N] ||
208  vars_w[VAR_T] || vars_h[VAR_T] ||
209  vars_w[VAR_POS] || vars_h[VAR_POS] ||
210  vars_w[VAR_S2R_MAIN_N] || vars_h[VAR_S2R_MAIN_N] ||
211  vars_w[VAR_S2R_MAIN_T] || vars_h[VAR_S2R_MAIN_T] ||
212  vars_w[VAR_S2R_MAIN_POS] || vars_h[VAR_S2R_MAIN_POS]) ) {
213  av_log(ctx, AV_LOG_ERROR, "Expressions with frame variables 'n', 't', 'pos' are not valid in init eval_mode.\n");
214  return AVERROR(EINVAL);
215  }
216 
217  return 0;
218 }
219 
220 static int scale_parse_expr(AVFilterContext *ctx, char *str_expr, AVExpr **pexpr_ptr, const char *var, const char *args)
221 {
222  ScaleContext *scale = ctx->priv;
223  int ret, is_inited = 0;
224  char *old_str_expr = NULL;
225  AVExpr *old_pexpr = NULL;
226 
227  if (str_expr) {
228  old_str_expr = av_strdup(str_expr);
229  if (!old_str_expr)
230  return AVERROR(ENOMEM);
231  av_opt_set(scale, var, args, 0);
232  }
233 
234  if (*pexpr_ptr) {
235  old_pexpr = *pexpr_ptr;
236  *pexpr_ptr = NULL;
237  is_inited = 1;
238  }
239 
240  ret = av_expr_parse(pexpr_ptr, args, var_names,
241  NULL, NULL, NULL, NULL, 0, ctx);
242  if (ret < 0) {
243  av_log(ctx, AV_LOG_ERROR, "Cannot parse expression for %s: '%s'\n", var, args);
244  goto revert;
245  }
246 
247  ret = check_exprs(ctx);
248  if (ret < 0)
249  goto revert;
250 
251  if (is_inited && (ret = config_props(ctx->outputs[0])) < 0)
252  goto revert;
253 
254  av_expr_free(old_pexpr);
255  old_pexpr = NULL;
256  av_freep(&old_str_expr);
257 
258  return 0;
259 
260 revert:
261  av_expr_free(*pexpr_ptr);
262  *pexpr_ptr = NULL;
263  if (old_str_expr) {
264  av_opt_set(scale, var, old_str_expr, 0);
265  av_free(old_str_expr);
266  }
267  if (old_pexpr)
268  *pexpr_ptr = old_pexpr;
269 
270  return ret;
271 }
272 
274 {
275  ScaleContext *scale = ctx->priv;
276  int ret;
277 
278  if (scale->size_str && (scale->w_expr || scale->h_expr)) {
279  av_log(ctx, AV_LOG_ERROR,
280  "Size and width/height expressions cannot be set at the same time.\n");
281  return AVERROR(EINVAL);
282  }
283 
284  if (scale->w_expr && !scale->h_expr)
285  FFSWAP(char *, scale->w_expr, scale->size_str);
286 
287  if (scale->size_str) {
288  char buf[32];
289  if ((ret = av_parse_video_size(&scale->w, &scale->h, scale->size_str)) < 0) {
290  av_log(ctx, AV_LOG_ERROR,
291  "Invalid size '%s'\n", scale->size_str);
292  return ret;
293  }
294  snprintf(buf, sizeof(buf)-1, "%d", scale->w);
295  av_opt_set(scale, "w", buf, 0);
296  snprintf(buf, sizeof(buf)-1, "%d", scale->h);
297  av_opt_set(scale, "h", buf, 0);
298  }
299  if (!scale->w_expr)
300  av_opt_set(scale, "w", "iw", 0);
301  if (!scale->h_expr)
302  av_opt_set(scale, "h", "ih", 0);
303 
304  ret = scale_parse_expr(ctx, NULL, &scale->w_pexpr, "width", scale->w_expr);
305  if (ret < 0)
306  return ret;
307 
308  ret = scale_parse_expr(ctx, NULL, &scale->h_pexpr, "height", scale->h_expr);
309  if (ret < 0)
310  return ret;
311 
312  av_log(ctx, AV_LOG_VERBOSE, "w:%s h:%s flags:'%s' interl:%d\n",
313  scale->w_expr, scale->h_expr, (char *)av_x_if_null(scale->flags_str, ""), scale->interlaced);
314 
315  scale->flags = 0;
316 
317  if (scale->flags_str) {
318  const AVClass *class = sws_get_class();
319  const AVOption *o = av_opt_find(&class, "sws_flags", NULL, 0,
321  int ret = av_opt_eval_flags(&class, o, scale->flags_str, &scale->flags);
322  if (ret < 0)
323  return ret;
324  }
325  scale->opts = *opts;
326  *opts = NULL;
327 
328  return 0;
329 }
330 
332 {
333  ScaleContext *scale = ctx->priv;
334  av_expr_free(scale->w_pexpr);
335  av_expr_free(scale->h_pexpr);
336  scale->w_pexpr = scale->h_pexpr = NULL;
337  sws_freeContext(scale->sws);
338  sws_freeContext(scale->isws[0]);
339  sws_freeContext(scale->isws[1]);
340  scale->sws = NULL;
341  av_dict_free(&scale->opts);
342 }
343 
345 {
347  enum AVPixelFormat pix_fmt;
348  int ret;
349 
350  if (ctx->inputs[0]) {
351  const AVPixFmtDescriptor *desc = NULL;
352  formats = NULL;
353  while ((desc = av_pix_fmt_desc_next(desc))) {
354  pix_fmt = av_pix_fmt_desc_get_id(desc);
355  if ((sws_isSupportedInput(pix_fmt) ||
357  && (ret = ff_add_format(&formats, pix_fmt)) < 0) {
358  return ret;
359  }
360  }
361  if ((ret = ff_formats_ref(formats, &ctx->inputs[0]->out_formats)) < 0)
362  return ret;
363  }
364  if (ctx->outputs[0]) {
365  const AVPixFmtDescriptor *desc = NULL;
366  formats = NULL;
367  while ((desc = av_pix_fmt_desc_next(desc))) {
368  pix_fmt = av_pix_fmt_desc_get_id(desc);
369  if ((sws_isSupportedOutput(pix_fmt) || pix_fmt == AV_PIX_FMT_PAL8 ||
371  && (ret = ff_add_format(&formats, pix_fmt)) < 0) {
372  return ret;
373  }
374  }
375  if ((ret = ff_formats_ref(formats, &ctx->outputs[0]->in_formats)) < 0)
376  return ret;
377  }
378 
379  return 0;
380 }
381 
382 static const int *parse_yuv_type(const char *s, enum AVColorSpace colorspace)
383 {
384  if (!s)
385  s = "bt601";
386 
387  if (s && strstr(s, "bt709")) {
388  colorspace = AVCOL_SPC_BT709;
389  } else if (s && strstr(s, "fcc")) {
390  colorspace = AVCOL_SPC_FCC;
391  } else if (s && strstr(s, "smpte240m")) {
392  colorspace = AVCOL_SPC_SMPTE240M;
393  } else if (s && (strstr(s, "bt601") || strstr(s, "bt470") || strstr(s, "smpte170m"))) {
394  colorspace = AVCOL_SPC_BT470BG;
395  } else if (s && strstr(s, "bt2020")) {
396  colorspace = AVCOL_SPC_BT2020_NCL;
397  }
398 
399  if (colorspace < 1 || colorspace > 10 || colorspace == 8) {
400  colorspace = AVCOL_SPC_BT470BG;
401  }
402 
403  return sws_getCoefficients(colorspace);
404 }
405 
407 {
408  ScaleContext *scale = ctx->priv;
409  const char scale2ref = ctx->filter == &ff_vf_scale2ref;
410  const AVFilterLink *inlink = scale2ref ? ctx->inputs[1] : ctx->inputs[0];
411  const AVFilterLink *outlink = ctx->outputs[0];
413  const AVPixFmtDescriptor *out_desc = av_pix_fmt_desc_get(outlink->format);
414  char *expr;
415  int eval_w, eval_h;
416  int ret;
417  double res;
418  const AVPixFmtDescriptor *main_desc;
419  const AVFilterLink *main_link;
420 
421  if (scale2ref) {
422  main_link = ctx->inputs[0];
423  main_desc = av_pix_fmt_desc_get(main_link->format);
424  }
425 
426  scale->var_values[VAR_IN_W] = scale->var_values[VAR_IW] = inlink->w;
427  scale->var_values[VAR_IN_H] = scale->var_values[VAR_IH] = inlink->h;
428  scale->var_values[VAR_OUT_W] = scale->var_values[VAR_OW] = NAN;
429  scale->var_values[VAR_OUT_H] = scale->var_values[VAR_OH] = NAN;
430  scale->var_values[VAR_A] = (double) inlink->w / inlink->h;
431  scale->var_values[VAR_SAR] = inlink->sample_aspect_ratio.num ?
432  (double) inlink->sample_aspect_ratio.num / inlink->sample_aspect_ratio.den : 1;
433  scale->var_values[VAR_DAR] = scale->var_values[VAR_A] * scale->var_values[VAR_SAR];
434  scale->var_values[VAR_HSUB] = 1 << desc->log2_chroma_w;
435  scale->var_values[VAR_VSUB] = 1 << desc->log2_chroma_h;
436  scale->var_values[VAR_OHSUB] = 1 << out_desc->log2_chroma_w;
437  scale->var_values[VAR_OVSUB] = 1 << out_desc->log2_chroma_h;
438 
439  if (scale2ref) {
440  scale->var_values[VAR_S2R_MAIN_W] = main_link->w;
441  scale->var_values[VAR_S2R_MAIN_H] = main_link->h;
442  scale->var_values[VAR_S2R_MAIN_A] = (double) main_link->w / main_link->h;
443  scale->var_values[VAR_S2R_MAIN_SAR] = main_link->sample_aspect_ratio.num ?
444  (double) main_link->sample_aspect_ratio.num / main_link->sample_aspect_ratio.den : 1;
447  scale->var_values[VAR_S2R_MAIN_HSUB] = 1 << main_desc->log2_chroma_w;
448  scale->var_values[VAR_S2R_MAIN_VSUB] = 1 << main_desc->log2_chroma_h;
449  }
450 
451  res = av_expr_eval(scale->w_pexpr, scale->var_values, NULL);
452  eval_w = scale->var_values[VAR_OUT_W] = scale->var_values[VAR_OW] = (int) res == 0 ? inlink->w : (int) res;
453 
454  res = av_expr_eval(scale->h_pexpr, scale->var_values, NULL);
455  if (isnan(res)) {
456  expr = scale->h_expr;
457  ret = AVERROR(EINVAL);
458  goto fail;
459  }
460  eval_h = scale->var_values[VAR_OUT_H] = scale->var_values[VAR_OH] = (int) res == 0 ? inlink->h : (int) res;
461 
462  res = av_expr_eval(scale->w_pexpr, scale->var_values, NULL);
463  if (isnan(res)) {
464  expr = scale->w_expr;
465  ret = AVERROR(EINVAL);
466  goto fail;
467  }
468  eval_w = scale->var_values[VAR_OUT_W] = scale->var_values[VAR_OW] = (int) res == 0 ? inlink->w : (int) res;
469 
470  scale->w = eval_w;
471  scale->h = eval_h;
472 
473  return 0;
474 
475 fail:
476  av_log(ctx, AV_LOG_ERROR,
477  "Error when evaluating the expression '%s'.\n", expr);
478  return ret;
479 }
480 
481 static int config_props(AVFilterLink *outlink)
482 {
483  AVFilterContext *ctx = outlink->src;
484  AVFilterLink *inlink0 = outlink->src->inputs[0];
485  AVFilterLink *inlink = ctx->filter == &ff_vf_scale2ref ?
486  outlink->src->inputs[1] :
487  outlink->src->inputs[0];
488  enum AVPixelFormat outfmt = outlink->format;
490  ScaleContext *scale = ctx->priv;
491  int ret;
492 
493  if ((ret = scale_eval_dimensions(ctx)) < 0)
494  goto fail;
495 
496  ff_scale_adjust_dimensions(inlink, &scale->w, &scale->h,
498  scale->force_divisible_by);
499 
500  if (scale->w > INT_MAX ||
501  scale->h > INT_MAX ||
502  (scale->h * inlink->w) > INT_MAX ||
503  (scale->w * inlink->h) > INT_MAX)
504  av_log(ctx, AV_LOG_ERROR, "Rescaled value for width or height is too big.\n");
505 
506  outlink->w = scale->w;
507  outlink->h = scale->h;
508 
509  /* TODO: make algorithm configurable */
510 
511  scale->input_is_pal = desc->flags & AV_PIX_FMT_FLAG_PAL;
512  if (outfmt == AV_PIX_FMT_PAL8) outfmt = AV_PIX_FMT_BGR8;
515 
516  if (scale->sws)
517  sws_freeContext(scale->sws);
518  if (scale->isws[0])
519  sws_freeContext(scale->isws[0]);
520  if (scale->isws[1])
521  sws_freeContext(scale->isws[1]);
522  scale->isws[0] = scale->isws[1] = scale->sws = NULL;
523  if (inlink0->w == outlink->w &&
524  inlink0->h == outlink->h &&
525  !scale->out_color_matrix &&
526  scale->in_range == scale->out_range &&
527  inlink0->format == outlink->format)
528  ;
529  else {
530  struct SwsContext **swscs[3] = {&scale->sws, &scale->isws[0], &scale->isws[1]};
531  int i;
532 
533  for (i = 0; i < 3; i++) {
534  int in_v_chr_pos = scale->in_v_chr_pos, out_v_chr_pos = scale->out_v_chr_pos;
535  struct SwsContext **s = swscs[i];
536  *s = sws_alloc_context();
537  if (!*s)
538  return AVERROR(ENOMEM);
539 
540  av_opt_set_int(*s, "srcw", inlink0 ->w, 0);
541  av_opt_set_int(*s, "srch", inlink0 ->h >> !!i, 0);
542  av_opt_set_int(*s, "src_format", inlink0->format, 0);
543  av_opt_set_int(*s, "dstw", outlink->w, 0);
544  av_opt_set_int(*s, "dsth", outlink->h >> !!i, 0);
545  av_opt_set_int(*s, "dst_format", outfmt, 0);
546  av_opt_set_int(*s, "sws_flags", scale->flags, 0);
547  av_opt_set_int(*s, "param0", scale->param[0], 0);
548  av_opt_set_int(*s, "param1", scale->param[1], 0);
549  if (scale->in_range != AVCOL_RANGE_UNSPECIFIED)
550  av_opt_set_int(*s, "src_range",
551  scale->in_range == AVCOL_RANGE_JPEG, 0);
552  if (scale->out_range != AVCOL_RANGE_UNSPECIFIED)
553  av_opt_set_int(*s, "dst_range",
554  scale->out_range == AVCOL_RANGE_JPEG, 0);
555 
556  if (scale->opts) {
557  AVDictionaryEntry *e = NULL;
558  while ((e = av_dict_get(scale->opts, "", e, AV_DICT_IGNORE_SUFFIX))) {
559  if ((ret = av_opt_set(*s, e->key, e->value, 0)) < 0)
560  return ret;
561  }
562  }
563  /* Override YUV420P default settings to have the correct (MPEG-2) chroma positions
564  * MPEG-2 chroma positions are used by convention
565  * XXX: support other 4:2:0 pixel formats */
566  if (inlink0->format == AV_PIX_FMT_YUV420P && scale->in_v_chr_pos == -513) {
567  in_v_chr_pos = (i == 0) ? 128 : (i == 1) ? 64 : 192;
568  }
569 
570  if (outlink->format == AV_PIX_FMT_YUV420P && scale->out_v_chr_pos == -513) {
571  out_v_chr_pos = (i == 0) ? 128 : (i == 1) ? 64 : 192;
572  }
573 
574  av_opt_set_int(*s, "src_h_chr_pos", scale->in_h_chr_pos, 0);
575  av_opt_set_int(*s, "src_v_chr_pos", in_v_chr_pos, 0);
576  av_opt_set_int(*s, "dst_h_chr_pos", scale->out_h_chr_pos, 0);
577  av_opt_set_int(*s, "dst_v_chr_pos", out_v_chr_pos, 0);
578 
579  if ((ret = sws_init_context(*s, NULL, NULL)) < 0)
580  return ret;
581  if (!scale->interlaced)
582  break;
583  }
584  }
585 
586  if (inlink0->sample_aspect_ratio.num){
587  outlink->sample_aspect_ratio = av_mul_q((AVRational){outlink->h * inlink0->w, outlink->w * inlink0->h}, inlink0->sample_aspect_ratio);
588  } else
589  outlink->sample_aspect_ratio = inlink0->sample_aspect_ratio;
590 
591  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",
592  inlink ->w, inlink ->h, av_get_pix_fmt_name( inlink->format),
594  outlink->w, outlink->h, av_get_pix_fmt_name(outlink->format),
595  outlink->sample_aspect_ratio.num, outlink->sample_aspect_ratio.den,
596  scale->flags);
597  return 0;
598 
599 fail:
600  return ret;
601 }
602 
603 static int config_props_ref(AVFilterLink *outlink)
604 {
605  AVFilterLink *inlink = outlink->src->inputs[1];
606 
607  outlink->w = inlink->w;
608  outlink->h = inlink->h;
609  outlink->sample_aspect_ratio = inlink->sample_aspect_ratio;
610  outlink->time_base = inlink->time_base;
611  outlink->frame_rate = inlink->frame_rate;
612 
613  return 0;
614 }
615 
616 static int request_frame(AVFilterLink *outlink)
617 {
618  return ff_request_frame(outlink->src->inputs[0]);
619 }
620 
621 static int request_frame_ref(AVFilterLink *outlink)
622 {
623  return ff_request_frame(outlink->src->inputs[1]);
624 }
625 
626 static int scale_slice(AVFilterLink *link, AVFrame *out_buf, AVFrame *cur_pic, struct SwsContext *sws, int y, int h, int mul, int field)
627 {
628  ScaleContext *scale = link->dst->priv;
629  const uint8_t *in[4];
630  uint8_t *out[4];
631  int in_stride[4],out_stride[4];
632  int i;
633 
634  for (i=0; i<4; i++) {
635  int vsub= ((i+1)&2) ? scale->vsub : 0;
636  in_stride[i] = cur_pic->linesize[i] * mul;
637  out_stride[i] = out_buf->linesize[i] * mul;
638  in[i] = FF_PTR_ADD(cur_pic->data[i], ((y>>vsub)+field) * cur_pic->linesize[i]);
639  out[i] = FF_PTR_ADD(out_buf->data[i], field * out_buf->linesize[i]);
640  }
641  if (scale->input_is_pal)
642  in[1] = cur_pic->data[1];
643  if (scale->output_is_pal)
644  out[1] = out_buf->data[1];
645 
646  return sws_scale(sws, in, in_stride, y/mul, h,
647  out,out_stride);
648 }
649 
650 #define TS2T(ts, tb) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts) * av_q2d(tb))
651 
652 static int scale_frame(AVFilterLink *link, AVFrame *in, AVFrame **frame_out)
653 {
654  AVFilterContext *ctx = link->dst;
655  ScaleContext *scale = ctx->priv;
656  AVFilterLink *outlink = ctx->outputs[0];
657  AVFrame *out;
659  char buf[32];
660  int in_range;
661  int frame_changed;
662 
663  *frame_out = NULL;
664  if (in->colorspace == AVCOL_SPC_YCGCO)
665  av_log(link->dst, AV_LOG_WARNING, "Detected unsupported YCgCo colorspace.\n");
666 
667  frame_changed = in->width != link->w ||
668  in->height != link->h ||
669  in->format != link->format ||
672 
673  if (scale->eval_mode == EVAL_MODE_FRAME || frame_changed) {
674  int ret;
675  unsigned vars_w[VARS_NB] = { 0 }, vars_h[VARS_NB] = { 0 };
676 
677  av_expr_count_vars(scale->w_pexpr, vars_w, VARS_NB);
678  av_expr_count_vars(scale->h_pexpr, vars_h, VARS_NB);
679 
680  if (scale->eval_mode == EVAL_MODE_FRAME &&
681  !frame_changed &&
682  ctx->filter != &ff_vf_scale2ref &&
683  !(vars_w[VAR_N] || vars_w[VAR_T] || vars_w[VAR_POS]) &&
684  !(vars_h[VAR_N] || vars_h[VAR_T] || vars_h[VAR_POS]) &&
685  scale->w && scale->h)
686  goto scale;
687 
688  if (scale->eval_mode == EVAL_MODE_INIT) {
689  snprintf(buf, sizeof(buf)-1, "%d", outlink->w);
690  av_opt_set(scale, "w", buf, 0);
691  snprintf(buf, sizeof(buf)-1, "%d", outlink->h);
692  av_opt_set(scale, "h", buf, 0);
693 
694  ret = scale_parse_expr(ctx, NULL, &scale->w_pexpr, "width", scale->w_expr);
695  if (ret < 0)
696  return ret;
697 
698  ret = scale_parse_expr(ctx, NULL, &scale->h_pexpr, "height", scale->h_expr);
699  if (ret < 0)
700  return ret;
701  }
702 
703  if (ctx->filter == &ff_vf_scale2ref) {
704  scale->var_values[VAR_S2R_MAIN_N] = link->frame_count_out;
705  scale->var_values[VAR_S2R_MAIN_T] = TS2T(in->pts, link->time_base);
706  scale->var_values[VAR_S2R_MAIN_POS] = in->pkt_pos == -1 ? NAN : in->pkt_pos;
707  } else {
708  scale->var_values[VAR_N] = link->frame_count_out;
709  scale->var_values[VAR_T] = TS2T(in->pts, link->time_base);
710  scale->var_values[VAR_POS] = in->pkt_pos == -1 ? NAN : in->pkt_pos;
711  }
712 
713  link->dst->inputs[0]->format = in->format;
714  link->dst->inputs[0]->w = in->width;
715  link->dst->inputs[0]->h = in->height;
716 
719 
720  if ((ret = config_props(outlink)) < 0)
721  return ret;
722  }
723 
724 scale:
725  if (!scale->sws) {
726  *frame_out = in;
727  return 0;
728  }
729 
730  scale->hsub = desc->log2_chroma_w;
731  scale->vsub = desc->log2_chroma_h;
732 
733  out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
734  if (!out) {
735  av_frame_free(&in);
736  return AVERROR(ENOMEM);
737  }
738  *frame_out = out;
739 
740  av_frame_copy_props(out, in);
741  out->width = outlink->w;
742  out->height = outlink->h;
743 
744  if (scale->output_is_pal)
745  avpriv_set_systematic_pal2((uint32_t*)out->data[1], outlink->format == AV_PIX_FMT_PAL8 ? AV_PIX_FMT_BGR8 : outlink->format);
746 
747  in_range = in->color_range;
748 
749  if ( scale->in_color_matrix
750  || scale->out_color_matrix
751  || scale-> in_range != AVCOL_RANGE_UNSPECIFIED
752  || in_range != AVCOL_RANGE_UNSPECIFIED
753  || scale->out_range != AVCOL_RANGE_UNSPECIFIED) {
754  int in_full, out_full, brightness, contrast, saturation;
755  const int *inv_table, *table;
756 
757  sws_getColorspaceDetails(scale->sws, (int **)&inv_table, &in_full,
758  (int **)&table, &out_full,
759  &brightness, &contrast, &saturation);
760 
761  if (scale->in_color_matrix)
762  inv_table = parse_yuv_type(scale->in_color_matrix, in->colorspace);
763  if (scale->out_color_matrix)
765  else if (scale->in_color_matrix)
766  table = inv_table;
767 
768  if (scale-> in_range != AVCOL_RANGE_UNSPECIFIED)
769  in_full = (scale-> in_range == AVCOL_RANGE_JPEG);
770  else if (in_range != AVCOL_RANGE_UNSPECIFIED)
771  in_full = (in_range == AVCOL_RANGE_JPEG);
772  if (scale->out_range != AVCOL_RANGE_UNSPECIFIED)
773  out_full = (scale->out_range == AVCOL_RANGE_JPEG);
774 
775  sws_setColorspaceDetails(scale->sws, inv_table, in_full,
776  table, out_full,
777  brightness, contrast, saturation);
778  if (scale->isws[0])
779  sws_setColorspaceDetails(scale->isws[0], inv_table, in_full,
780  table, out_full,
781  brightness, contrast, saturation);
782  if (scale->isws[1])
783  sws_setColorspaceDetails(scale->isws[1], inv_table, in_full,
784  table, out_full,
785  brightness, contrast, saturation);
786 
787  out->color_range = out_full ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG;
788  }
789 
791  (int64_t)in->sample_aspect_ratio.num * outlink->h * link->w,
792  (int64_t)in->sample_aspect_ratio.den * outlink->w * link->h,
793  INT_MAX);
794 
795  if (scale->interlaced>0 || (scale->interlaced<0 && in->interlaced_frame)) {
796  scale_slice(link, out, in, scale->isws[0], 0, (link->h+1)/2, 2, 0);
797  scale_slice(link, out, in, scale->isws[1], 0, link->h /2, 2, 1);
798  } else if (scale->nb_slices) {
799  int i, slice_h, slice_start, slice_end = 0;
800  const int nb_slices = FFMIN(scale->nb_slices, link->h);
801  for (i = 0; i < nb_slices; i++) {
802  slice_start = slice_end;
803  slice_end = (link->h * (i+1)) / nb_slices;
804  slice_h = slice_end - slice_start;
805  scale_slice(link, out, in, scale->sws, slice_start, slice_h, 1, 0);
806  }
807  } else {
808  scale_slice(link, out, in, scale->sws, 0, link->h, 1, 0);
809  }
810 
811  av_frame_free(&in);
812  return 0;
813 }
814 
815 static int filter_frame(AVFilterLink *link, AVFrame *in)
816 {
817  AVFilterContext *ctx = link->dst;
818  AVFilterLink *outlink = ctx->outputs[0];
819  AVFrame *out;
820  int ret;
821 
822  ret = scale_frame(link, in, &out);
823  if (out)
824  return ff_filter_frame(outlink, out);
825 
826  return ret;
827 }
828 
830 {
831  ScaleContext *scale = link->dst->priv;
832  AVFilterLink *outlink = link->dst->outputs[1];
833  int frame_changed;
834 
835  frame_changed = in->width != link->w ||
836  in->height != link->h ||
837  in->format != link->format ||
840 
841  if (frame_changed) {
842  link->format = in->format;
843  link->w = in->width;
844  link->h = in->height;
847 
848  config_props_ref(outlink);
849  }
850 
851  if (scale->eval_mode == EVAL_MODE_FRAME) {
852  scale->var_values[VAR_N] = link->frame_count_out;
853  scale->var_values[VAR_T] = TS2T(in->pts, link->time_base);
854  scale->var_values[VAR_POS] = in->pkt_pos == -1 ? NAN : in->pkt_pos;
855  }
856 
857  return ff_filter_frame(outlink, in);
858 }
859 
860 static int process_command(AVFilterContext *ctx, const char *cmd, const char *args,
861  char *res, int res_len, int flags)
862 {
863  ScaleContext *scale = ctx->priv;
864  char *str_expr;
865  AVExpr **pexpr_ptr;
866  int ret, w, h;
867 
868  w = !strcmp(cmd, "width") || !strcmp(cmd, "w");
869  h = !strcmp(cmd, "height") || !strcmp(cmd, "h");
870 
871  if (w || h) {
872  str_expr = w ? scale->w_expr : scale->h_expr;
873  pexpr_ptr = w ? &scale->w_pexpr : &scale->h_pexpr;
874 
875  ret = scale_parse_expr(ctx, str_expr, pexpr_ptr, cmd, args);
876  } else
877  ret = AVERROR(ENOSYS);
878 
879  if (ret < 0)
880  av_log(ctx, AV_LOG_ERROR, "Failed to process command. Continuing with existing parameters.\n");
881 
882  return ret;
883 }
884 
885 static const AVClass *child_class_next(const AVClass *prev)
886 {
887  return prev ? NULL : sws_get_class();
888 }
889 
890 #define OFFSET(x) offsetof(ScaleContext, x)
891 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
892 #define TFLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_RUNTIME_PARAM
893 
894 static const AVOption scale_options[] = {
895  { "w", "Output video width", OFFSET(w_expr), AV_OPT_TYPE_STRING, .flags = TFLAGS },
896  { "width", "Output video width", OFFSET(w_expr), AV_OPT_TYPE_STRING, .flags = TFLAGS },
897  { "h", "Output video height", OFFSET(h_expr), AV_OPT_TYPE_STRING, .flags = TFLAGS },
898  { "height","Output video height", OFFSET(h_expr), AV_OPT_TYPE_STRING, .flags = TFLAGS },
899  { "flags", "Flags to pass to libswscale", OFFSET(flags_str), AV_OPT_TYPE_STRING, { .str = "bilinear" }, .flags = FLAGS },
900  { "interl", "set interlacing", OFFSET(interlaced), AV_OPT_TYPE_BOOL, {.i64 = 0 }, -1, 1, FLAGS },
901  { "size", "set video size", OFFSET(size_str), AV_OPT_TYPE_STRING, {.str = NULL}, 0, FLAGS },
902  { "s", "set video size", OFFSET(size_str), AV_OPT_TYPE_STRING, {.str = NULL}, 0, FLAGS },
903  { "in_color_matrix", "set input YCbCr type", OFFSET(in_color_matrix), AV_OPT_TYPE_STRING, { .str = "auto" }, .flags = FLAGS, "color" },
904  { "out_color_matrix", "set output YCbCr type", OFFSET(out_color_matrix), AV_OPT_TYPE_STRING, { .str = NULL }, .flags = FLAGS, "color"},
905  { "auto", NULL, 0, AV_OPT_TYPE_CONST, { .str = "auto" }, 0, 0, FLAGS, "color" },
906  { "bt601", NULL, 0, AV_OPT_TYPE_CONST, { .str = "bt601" }, 0, 0, FLAGS, "color" },
907  { "bt470", NULL, 0, AV_OPT_TYPE_CONST, { .str = "bt470" }, 0, 0, FLAGS, "color" },
908  { "smpte170m", NULL, 0, AV_OPT_TYPE_CONST, { .str = "smpte170m" }, 0, 0, FLAGS, "color" },
909  { "bt709", NULL, 0, AV_OPT_TYPE_CONST, { .str = "bt709" }, 0, 0, FLAGS, "color" },
910  { "fcc", NULL, 0, AV_OPT_TYPE_CONST, { .str = "fcc" }, 0, 0, FLAGS, "color" },
911  { "smpte240m", NULL, 0, AV_OPT_TYPE_CONST, { .str = "smpte240m" }, 0, 0, FLAGS, "color" },
912  { "bt2020", NULL, 0, AV_OPT_TYPE_CONST, { .str = "bt2020" }, 0, 0, FLAGS, "color" },
913  { "in_range", "set input color range", OFFSET( in_range), AV_OPT_TYPE_INT, {.i64 = AVCOL_RANGE_UNSPECIFIED }, 0, 2, FLAGS, "range" },
914  { "out_range", "set output color range", OFFSET(out_range), AV_OPT_TYPE_INT, {.i64 = AVCOL_RANGE_UNSPECIFIED }, 0, 2, FLAGS, "range" },
915  { "auto", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_UNSPECIFIED }, 0, 0, FLAGS, "range" },
916  { "unknown", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_UNSPECIFIED }, 0, 0, FLAGS, "range" },
917  { "full", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_JPEG}, 0, 0, FLAGS, "range" },
918  { "limited",NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_MPEG}, 0, 0, FLAGS, "range" },
919  { "jpeg", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_JPEG}, 0, 0, FLAGS, "range" },
920  { "mpeg", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_MPEG}, 0, 0, FLAGS, "range" },
921  { "tv", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_MPEG}, 0, 0, FLAGS, "range" },
922  { "pc", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_JPEG}, 0, 0, FLAGS, "range" },
923  { "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 },
924  { "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 },
925  { "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 },
926  { "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 },
927  { "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" },
928  { "disable", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 0 }, 0, 0, FLAGS, "force_oar" },
929  { "decrease", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 1 }, 0, 0, FLAGS, "force_oar" },
930  { "increase", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 2 }, 0, 0, FLAGS, "force_oar" },
931  { "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 },
932  { "param0", "Scaler param 0", OFFSET(param[0]), AV_OPT_TYPE_DOUBLE, { .dbl = SWS_PARAM_DEFAULT }, INT_MIN, INT_MAX, FLAGS },
933  { "param1", "Scaler param 1", OFFSET(param[1]), AV_OPT_TYPE_DOUBLE, { .dbl = SWS_PARAM_DEFAULT }, INT_MIN, INT_MAX, FLAGS },
934  { "nb_slices", "set the number of slices (debug purpose only)", OFFSET(nb_slices), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, FLAGS },
935  { "eval", "specify when to evaluate expressions", OFFSET(eval_mode), AV_OPT_TYPE_INT, {.i64 = EVAL_MODE_INIT}, 0, EVAL_MODE_NB-1, FLAGS, "eval" },
936  { "init", "eval expressions once during initialization", 0, AV_OPT_TYPE_CONST, {.i64=EVAL_MODE_INIT}, .flags = FLAGS, .unit = "eval" },
937  { "frame", "eval expressions during initialization and per-frame", 0, AV_OPT_TYPE_CONST, {.i64=EVAL_MODE_FRAME}, .flags = FLAGS, .unit = "eval" },
938  { NULL }
939 };
940 
941 static const AVClass scale_class = {
942  .class_name = "scale",
943  .item_name = av_default_item_name,
944  .option = scale_options,
945  .version = LIBAVUTIL_VERSION_INT,
946  .category = AV_CLASS_CATEGORY_FILTER,
947  .child_class_next = child_class_next,
948 };
949 
951  {
952  .name = "default",
953  .type = AVMEDIA_TYPE_VIDEO,
954  .filter_frame = filter_frame,
955  },
956  { NULL }
957 };
958 
960  {
961  .name = "default",
962  .type = AVMEDIA_TYPE_VIDEO,
963  .config_props = config_props,
964  },
965  { NULL }
966 };
967 
969  .name = "scale",
970  .description = NULL_IF_CONFIG_SMALL("Scale the input video size and/or convert the image format."),
971  .init_dict = init_dict,
972  .uninit = uninit,
973  .query_formats = query_formats,
974  .priv_size = sizeof(ScaleContext),
975  .priv_class = &scale_class,
976  .inputs = avfilter_vf_scale_inputs,
977  .outputs = avfilter_vf_scale_outputs,
979 };
980 
981 static const AVClass scale2ref_class = {
982  .class_name = "scale2ref",
983  .item_name = av_default_item_name,
984  .option = scale_options,
985  .version = LIBAVUTIL_VERSION_INT,
986  .category = AV_CLASS_CATEGORY_FILTER,
987  .child_class_next = child_class_next,
988 };
989 
991  {
992  .name = "default",
993  .type = AVMEDIA_TYPE_VIDEO,
994  .filter_frame = filter_frame,
995  },
996  {
997  .name = "ref",
998  .type = AVMEDIA_TYPE_VIDEO,
999  .filter_frame = filter_frame_ref,
1000  },
1001  { NULL }
1002 };
1003 
1005  {
1006  .name = "default",
1007  .type = AVMEDIA_TYPE_VIDEO,
1008  .config_props = config_props,
1009  .request_frame= request_frame,
1010  },
1011  {
1012  .name = "ref",
1013  .type = AVMEDIA_TYPE_VIDEO,
1014  .config_props = config_props_ref,
1015  .request_frame= request_frame_ref,
1016  },
1017  { NULL }
1018 };
1019 
1020 AVFilter ff_vf_scale2ref = {
1021  .name = "scale2ref",
1022  .description = NULL_IF_CONFIG_SMALL("Scale the input video size and/or convert the image format to the given reference."),
1023  .init_dict = init_dict,
1024  .uninit = uninit,
1025  .query_formats = query_formats,
1026  .priv_size = sizeof(ScaleContext),
1027  .priv_class = &scale2ref_class,
1028  .inputs = avfilter_vf_scale2ref_inputs,
1029  .outputs = avfilter_vf_scale2ref_outputs,
1031 };
#define AV_PIX_FMT_FLAG_PAL
Pixel format has a palette in data[1], values are indexes in this palette.
Definition: pixdesc.h:132
also ITU-R BT1361 / IEC 61966-2-4 xvYCC709 / SMPTE RP177 Annex B
Definition: pixfmt.h:511
#define NULL
Definition: coverity.c:32
static av_cold int init_dict(AVFilterContext *ctx, AVDictionary **opts)
Definition: vf_scale.c:273
static enum AVPixelFormat pix_fmt
#define FLAGS
Definition: vf_scale.c:891
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2549
This structure describes decoded (raw) audio or video data.
Definition: frame.h:300
int in_h_chr_pos
Definition: vf_scale.c:146
AVOption.
Definition: opt.h:246
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:148
int64_t pkt_pos
reordered pos from the last AVPacket that has been input into the decoder
Definition: frame.h:571
misc image utilities
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:182
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
Main libavfilter public API header.
AVExpr * w_pexpr
Definition: vf_scale.c:132
const char * desc
Definition: nvenc.c:79
int sws_getColorspaceDetails(struct SwsContext *c, int **inv_table, int *srcRange, int **table, int *dstRange, int *brightness, int *contrast, int *saturation)
Definition: utils.c:998
also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM / IEC 61966-2-4 xvYCC601 ...
Definition: pixfmt.h:515
Definition: vf_scale.c:86
static int scale_slice(AVFilterLink *link, AVFrame *out_buf, AVFrame *cur_pic, struct SwsContext *sws, int y, int h, int mul, int field)
Definition: vf_scale.c:626
int num
Numerator.
Definition: rational.h:59
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:235
int in_v_chr_pos
Definition: vf_scale.c:147
int out_h_chr_pos
Definition: vf_scale.c:144
int eval_mode
expression evaluation mode
Definition: vf_scale.c:154
int sws_isSupportedEndiannessConversion(enum AVPixelFormat pix_fmt)
Definition: utils.c:288
int force_original_aspect_ratio
Definition: vf_scale.c:149
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:685
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.
Definition: video.c:104
const AVClass * sws_get_class(void)
Get the AVClass for swsContext.
Definition: options.c:95
Definition: vf_scale.c:85
int vsub
chroma subsampling
Definition: vf_scale.c:124
uint8_t log2_chroma_w
Amount to shift the luma width right to find the chroma width.
Definition: pixdesc.h:92
int output_is_pal
set to 1 if the output format is paletted
Definition: vf_scale.c:127
functionally identical to above
Definition: pixfmt.h:517
const char * name
Pad name.
Definition: internal.h:60
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:72
AVFilterLink ** inputs
array of pointers to input links
Definition: avfilter.h:346
char * w_expr
width expression string
Definition: vf_scale.c:130
static int query_formats(AVFilterContext *ctx)
Definition: vf_scale.c:344
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1075
uint8_t
#define av_cold
Definition: attributes.h:88
av_warn_unused_result int sws_init_context(struct SwsContext *sws_context, SwsFilter *srcFilter, SwsFilter *dstFilter)
Initialize the swscaler context sws_context.
Definition: utils.c:1170
char * h_expr
height expression string
Definition: vf_scale.c:131
8 bits with AV_PIX_FMT_RGB32 palette
Definition: pixfmt.h:77
AVOptions.
AVColorSpace
YUV colorspace type.
Definition: pixfmt.h:509
int avpriv_set_systematic_pal2(uint32_t pal[256], enum AVPixelFormat pix_fmt)
Definition: imgutils.c:152
Used by Dirac / VC-2 and H.264 FRext, see ITU-T SG16.
Definition: pixfmt.h:518
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:393
Definition: eval.c:157
AVFilter ff_vf_scale2ref
Definition: vf_scale.c:158
static const int * parse_yuv_type(const char *s, enum AVColorSpace colorspace)
Definition: vf_scale.c:382
AVDictionaryEntry * av_dict_get(const AVDictionary *m, const char *key, const AVDictionaryEntry *prev, int flags)
Get a dictionary entry with matching key.
Definition: dict.c:40
static const AVClass scale_class
Definition: vf_scale.c:941
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:192
int interlaced_frame
The content of the picture is interlaced.
Definition: frame.h:447
external API header
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
static int scale_frame(AVFilterLink *link, AVFrame *in, AVFrame **frame_out)
Definition: vf_scale.c:652
#define av_log(a,...)
#define FF_PTR_ADD(ptr, off)
Definition: internal.h:176
static const uint16_t table[]
Definition: prosumer.c:206
A filter pad used for either input or output.
Definition: internal.h:54
static void * av_x_if_null(const void *p, const void *x)
Return x default pointer in case p is NULL.
Definition: avutil.h:308
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:269
int width
Definition: frame.h:358
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
uint8_t log2_chroma_h
Amount to shift the luma height right to find the chroma height.
Definition: pixdesc.h:101
static const AVClass scale2ref_class
Definition: vf_scale.c:981
static const AVOption scale_options[]
Definition: vf_scale.c:894
#define AVERROR(e)
Definition: error.h:43
int av_opt_eval_flags(void *obj, const AVOption *o, const char *val, int *flags_out)
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:203
#define sws_isSupportedOutput(x)
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:188
void * priv
private data for use by the filter
Definition: avfilter.h:353
enum AVColorRange color_range
MPEG vs JPEG YUV range.
Definition: frame.h:544
void av_dict_free(AVDictionary **pm)
Free all the memory allocated for an AVDictionary struct and all keys and values. ...
Definition: dict.c:203
int av_opt_set_int(void *obj, const char *name, int64_t val, int search_flags)
Definition: opt.c:586
enum AVColorSpace colorspace
YUV colorspace type.
Definition: frame.h:555
simple assert() macros that are a bit more flexible than ISO C assert().
int ff_add_format(AVFilterFormats **avff, int64_t fmt)
Add fmt to the list of media formats contained in *avff.
Definition: formats.c:350
#define fail()
Definition: checkasm.h:123
static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, char *res, int res_len, int flags)
Definition: vf_scale.c:860
static int scale_parse_expr(AVFilterContext *ctx, char *str_expr, AVExpr **pexpr_ptr, const char *var, const char *args)
Definition: vf_scale.c:220
int w
New dimensions.
Definition: vf_scale.c:119
static int config_props(AVFilterLink *outlink)
Definition: vf_scale.c:481
var_name
Definition: aeval.c:46
const AVOption * av_opt_find(void *obj, const char *name, const char *unit, int opt_flags, int search_flags)
Look for an option in an object.
Definition: opt.c:1660
common internal API header
uint64_t flags
Combination of AV_PIX_FMT_FLAG_...
Definition: pixdesc.h:106
char * out_color_matrix
Definition: vf_scale.c:139
enum AVPixelFormat av_pix_fmt_desc_get_id(const AVPixFmtDescriptor *desc)
Definition: pixdesc.c:2568
static av_cold void uninit(AVFilterContext *ctx)
Definition: vf_scale.c:331
#define NAN
Definition: mathematics.h:64
static const AVFilterPad avfilter_vf_scale_outputs[]
Definition: vf_scale.c:959
#define FFMIN(a, b)
Definition: common.h:96
double param[2]
sws flags
Definition: vf_scale.c:122
int ff_formats_ref(AVFilterFormats *f, AVFilterFormats **ref)
Add *ref as a new reference to formats.
Definition: formats.c:484
static int request_frame(AVFilterLink *outlink)
Definition: vf_scale.c:616
ITU-R BT2020 non-constant luminance system.
Definition: pixfmt.h:520
static const AVClass * child_class_next(const AVClass *prev)
Definition: vf_scale.c:885
AVFormatContext * ctx
Definition: movenc.c:48
void sws_freeContext(struct SwsContext *swsContext)
Free the swscaler context swsContext.
Definition: utils.c:2319
#define s(width, name)
Definition: cbs_vp9.c:257
static int check_exprs(AVFilterContext *ctx)
Definition: vf_scale.c:162
int interlaced
Definition: vf_scale.c:128
const int * sws_getCoefficients(int colorspace)
Return a pointer to yuv<->rgb coefficients for the given colorspace suitable for sws_setColorspaceDet...
Definition: yuv2rgb.c:63
#define sws_isSupportedInput(x)
static const AVFilterPad inputs[]
Definition: af_acontrast.c:193
int sws_setColorspaceDetails(struct SwsContext *c, const int inv_table[4], int srcRange, const int table[4], int dstRange, int brightness, int contrast, int saturation)
Definition: utils.c:863
char * flags_str
Definition: vf_scale.c:136
static int scale_eval_dimensions(AVFilterContext *ctx)
Definition: vf_scale.c:406
FCC Title 47 Code of Federal Regulations 73.682 (a)(20)
Definition: pixfmt.h:514
EvalMode
Definition: af_volume.h:39
static const AVFilterPad outputs[]
Definition: af_acontrast.c:203
the normal 2^n-1 "JPEG" YUV ranges
Definition: pixfmt.h:535
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames...
Definition: frame.h:373
static int config_props_ref(AVFilterLink *outlink)
Definition: vf_scale.c:603
static int filter_frame_ref(AVFilterLink *link, AVFrame *in)
Definition: vf_scale.c:829
AVExpr * h_pexpr
Definition: vf_scale.c:133
packed RGB 3:3:2, 8bpp, (msb)2B 3G 3R(lsb)
Definition: pixfmt.h:83
#define OFFSET(x)
Definition: vf_scale.c:890
char * av_strdup(const char *s)
Duplicate a string.
Definition: mem.c:253
AVFilter ff_vf_scale
Definition: vf_scale.c:968
#define TFLAGS
Definition: vf_scale.c:892
void av_expr_free(AVExpr *e)
Free a parsed expression previously created with av_expr_parse().
Definition: eval.c:336
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:331
struct SwsContext * sws
software scaler context
Definition: vf_scale.c:109
static int request_frame_ref(AVFilterLink *outlink)
Definition: vf_scale.c:621
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:81
static const AVFilterPad avfilter_vf_scale_inputs[]
Definition: vf_scale.c:950
AVRational sample_aspect_ratio
Sample aspect ratio for the video frame, 0/1 if unknown/unspecified.
Definition: frame.h:388
static const AVFilterPad avfilter_vf_scale2ref_outputs[]
Definition: vf_scale.c:1004
AVDictionary * opts
Definition: vf_scale.c:111
int attribute_align_arg sws_scale(struct SwsContext *c, const uint8_t *const srcSlice[], const int srcStride[], int srcSliceY, int srcSliceH, uint8_t *const dst[], const int dstStride[])
swscale wrapper, so we don&#39;t need to export the SwsContext.
Definition: swscale.c:744
uint8_t pi<< 24) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi - 0x80) *(1.0f/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi - 0x80) *(1.0/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t,(*(const int16_t *) pi >> 8)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t, *(const int16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t, *(const int16_t *) pi *(1.0/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t,(*(const int32_t *) pi >> 24)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t, *(const int32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t, *(const int32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8(lrintf(*(const float *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16(lrintf(*(const float *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(const float *) pi *(1U<< 31)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8(lrint(*(const double *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16(lrint(*(const double *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(const double *) pi *(1U<< 31)))) #define SET_CONV_FUNC_GROUP(ofmt, ifmt) static void set_generic_function(AudioConvert *ac) { } void ff_audio_convert_free(AudioConvert **ac) { if(! *ac) return;ff_dither_free(&(*ac) ->dc);av_freep(ac);} AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, int sample_rate, int apply_map) { AudioConvert *ac;int in_planar, out_planar;ac=av_mallocz(sizeof(*ac));if(!ac) return NULL;ac->avr=avr;ac->out_fmt=out_fmt;ac->in_fmt=in_fmt;ac->channels=channels;ac->apply_map=apply_map;if(avr->dither_method !=AV_RESAMPLE_DITHER_NONE &&av_get_packed_sample_fmt(out_fmt)==AV_SAMPLE_FMT_S16 &&av_get_bytes_per_sample(in_fmt) > 2) { ac->dc=ff_dither_alloc(avr, out_fmt, in_fmt, channels, sample_rate, apply_map);if(!ac->dc) { av_free(ac);return NULL;} return ac;} in_planar=ff_sample_fmt_is_planar(in_fmt, channels);out_planar=ff_sample_fmt_is_planar(out_fmt, channels);if(in_planar==out_planar) { ac->func_type=CONV_FUNC_TYPE_FLAT;ac->planes=in_planar ? ac->channels :1;} else if(in_planar) ac->func_type=CONV_FUNC_TYPE_INTERLEAVE;else ac->func_type=CONV_FUNC_TYPE_DEINTERLEAVE;set_generic_function(ac);if(ARCH_AARCH64) ff_audio_convert_init_aarch64(ac);if(ARCH_ARM) ff_audio_convert_init_arm(ac);if(ARCH_X86) ff_audio_convert_init_x86(ac);return ac;} int ff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in) { int use_generic=1;int len=in->nb_samples;int p;if(ac->dc) { av_log(ac->avr, AV_LOG_TRACE, "%d samples - audio_convert: %s to %s (dithered)\", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));return ff_convert_dither(ac-> in
Describe the class of an AVClass context structure.
Definition: log.h:67
Filter definition.
Definition: avfilter.h:144
Rational number (pair of numerator and denominator).
Definition: rational.h:58
#define isnan(x)
Definition: libm.h:340
const char * name
Filter name.
Definition: avfilter.h:148
#define snprintf
Definition: snprintf.h:34
int input_is_pal
set to 1 if the input format is paletted
Definition: vf_scale.c:126
static const char *const var_names[]
Definition: vf_scale.c:45
unsigned int flags
Definition: vf_scale.c:121
misc parsing utilities
struct SwsContext * sws_alloc_context(void)
Allocate an empty SwsContext.
Definition: utils.c:1084
AVFilterLink ** outputs
array of pointers to output links
Definition: avfilter.h:350
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
int out_v_chr_pos
Definition: vf_scale.c:145
struct SwsContext * isws[2]
software scaler context for interlaced material
Definition: vf_scale.c:110
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:314
static int filter_frame(AVFilterLink *link, AVFrame *in)
Definition: vf_scale.c:815
int in_range
Definition: vf_scale.c:141
the normal 219*2^(n-8) "MPEG" YUV ranges
Definition: pixfmt.h:534
int
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:66
double var_values[VARS_NB]
Definition: vf_scale.c:134
int out_range
Definition: vf_scale.c:142
#define AV_OPT_SEARCH_FAKE_OBJ
The obj passed to av_opt_find() is fake – only a double pointer to AVClass instead of a required poi...
Definition: opt.h:567
char * size_str
Definition: vf_scale.c:120
char * key
Definition: dict.h:86
int den
Denominator.
Definition: rational.h:60
#define SWS_PARAM_DEFAULT
Definition: swscale.h:73
int slice_y
top of current output slice
Definition: vf_scale.c:125
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:756
Definition: vf_scale.c:78
static int slice_end(AVCodecContext *avctx, AVFrame *pict)
Handle slice ends.
Definition: mpeg12dec.c:2040
#define FF_PSEUDOPAL
Definition: internal.h:369
#define av_free(p)
char * value
Definition: dict.h:87
double av_expr_eval(AVExpr *e, const double *const_values, void *opaque)
Evaluate a previously parsed expression.
Definition: eval.c:766
char * in_color_matrix
Definition: vf_scale.c:138
int nb_slices
Definition: vf_scale.c:152
A list of supported formats for one end of a filter link.
Definition: formats.h:64
An instance of a filter.
Definition: avfilter.h:338
AVRational av_mul_q(AVRational b, AVRational c)
Multiply two rationals.
Definition: rational.c:80
int height
Definition: frame.h:358
FILE * out
Definition: movenc.c:54
#define av_freep(p)
#define AV_DICT_IGNORE_SUFFIX
Return first entry in a dictionary whose first part corresponds to the search key, ignoring the suffix of the found key string.
Definition: dict.h:70
int ff_request_frame(AVFilterLink *link)
Request an input frame from the filter at the other end of the link.
Definition: avfilter.c:407
formats
Definition: signature.h:48
#define FFSWAP(type, a, b)
Definition: common.h:99
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:2465
internal API functions
int force_divisible_by
Definition: vf_scale.c:150
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
int av_opt_set(void *obj, const char *name, const char *val, int search_flags)
Definition: opt.c:465
const AVFilter * filter
the AVFilter of which this is an instance
Definition: avfilter.h:341
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
Definition: frame.c:659
static const AVFilterPad avfilter_vf_scale2ref_inputs[]
Definition: vf_scale.c:990
simple arithmetic expression evaluator
#define TS2T(ts, tb)
Definition: vf_scale.c:650
const AVPixFmtDescriptor * av_pix_fmt_desc_next(const AVPixFmtDescriptor *prev)
Iterate over all pixel format descriptors known to libavutil.
Definition: pixdesc.c:2556