FFmpeg
filters.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2026 Niklas Haas
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 #include <math.h>
22 #include <stdbool.h>
23 
24 #include <libavutil/attributes.h>
25 #include <libavutil/avassert.h>
26 #include <libavutil/mem.h>
27 
28 #include "filters.h"
29 
30 #ifdef _WIN32
31 # define j1 _j1
32 #endif
33 
34 /* Maximum (pre-stretching) radius (for tunable filters) */
35 #define RADIUS_MAX 10.0
36 
37 /* Defined only on [0, radius]. */
38 typedef double (*SwsFilterKernel)(double x, const double *params);
39 
40 typedef struct SwsFilterFunction {
41  char name[16];
42  double radius; /* negative means resizable */
44  SwsFilterKernel window; /* optional */
45  double params[SWS_NUM_SCALER_PARAMS]; /* default params */
47 
49 
50 static double scaler_sample(const SwsFilterFunction *f, double x)
51 {
52  x = fabs(x);
53  if (x > f->radius)
54  return 0.0;
55 
56  double w = f->kernel(x, f->params);
57  if (f->window)
58  w *= f->window(x / f->radius, f->params);
59  return w;
60 }
61 
63  double radius, double ratio_inv, double stretch_inv,
64  int dst_pos, double *tmp)
65 {
66  int *out = &f->weights[dst_pos * f->filter_size];
67  int *pos = &f->offsets[dst_pos];
68 
69  /**
70  * Explanation of the 0.5 offsets: Normally, pixel samples are assumed
71  * to be representative of the center of their containing area; e.g. for
72  * a 2x2 image, the samples are located at {0.5, 1.5}^2. However, with
73  * integer indexing, we round sample positions down (0-based indexing).
74  * So the (0, 0) sample is actually located at (0.5, 0.5) and represents
75  * the entire square from (0,0) to (1,1). When normalizing between different
76  * image sizes, we therefore need to add/subtract off these 0.5 offsets.
77  */
78  const double src_pos = (dst_pos + 0.5) * ratio_inv - 0.5 + f->offset;
79  if (f->filter_size == 1) {
80  *pos = fmin(fmax(round(src_pos), 0.0), f->src_size - 1);
82  return;
83  }
84 
85  /* First pixel that is actually within the filter envelope */
86  const double start_pos = src_pos - radius;
87  int64_t start_idx = ceil(start_pos);
88  start_idx = FFMAX(start_idx, 0); /* edge clamping */
89  start_idx = FFMIN(start_idx, f->src_size - f->filter_size);
90  const double offset = start_idx - src_pos;
91  *pos = start_idx;
92 
93  /**
94  * Generate raw filter weights with maximum precision. Sum the positive
95  * and negative weights separately to avoid catastrophic cancellation. This
96  * summation order should already give the best precision because abs(w)
97  * is monotonically decreasing
98  */
99  const double base = stretch_inv * offset;
100  double wsum_pos = 0.0, wsum_neg = 0.0;
101  for (int i = 0; i < f->filter_size; i++) {
102  tmp[i] = scaler_sample(fun, base + stretch_inv * i);
103  if (tmp[i] >= 0)
104  wsum_pos += tmp[i];
105  else
106  wsum_neg += tmp[i];
107  }
108 
109  const double wsum = wsum_pos + wsum_neg;
110  av_assert0(wsum > 0);
111 
112  /* Generate correctly rounded filter weights with error diffusion */
113  double error = 0.0;
114  int sum_pos = 0, sum_neg = 0;
115  for (int i = 0; i < f->filter_size; i++) {
116  if (i == f->filter_size - 1) {
117  /* Ensure weights sum to exactly SWS_FILTER_SCALE */
118  out[i] = SWS_FILTER_SCALE - sum_pos - sum_neg;
119  } else {
120  const double w = tmp[i] / wsum + error;
121  out[i] = round(w * SWS_FILTER_SCALE);
122  error = w - (double) out[i] / SWS_FILTER_SCALE;
123  }
124  if (out[i] >= 0)
125  sum_pos += out[i];
126  else
127  sum_neg += out[i];
128  }
129 
130  if (sum_pos > f->sum_positive)
131  f->sum_positive = sum_pos;
132  if (sum_neg < f->sum_negative)
133  f->sum_negative = sum_neg;
134 }
135 
136 static void sws_filter_free(AVRefStructOpaque opaque, void *obj)
137 {
138  SwsFilterWeights *filter = obj;
139  av_refstruct_unref(&filter->weights);
140  av_refstruct_unref(&filter->offsets);
141 }
142 
143 static bool validate_params(const SwsFilterFunction *fun, SwsScaler scaler)
144 {
145  switch (scaler) {
146  case SWS_SCALE_GAUSSIAN:
147  return fun->params[0] >= 0.0; /* sigma */
148  case SWS_SCALE_LANCZOS:
149  return fun->params[0] >= 1.0 && fun->params[0] <= RADIUS_MAX; /* radius */
150  case SWS_SCALE_BICUBIC:
151  return fun->params[0] < 3.0; /* B param (division by zero) */
152  default:
153  return true;
154  }
155 }
156 
157 /**
158  * Numerically estimate the last intersection between the function value
159  * and the cutoff domain [-SWS_MAX_REDUCE_CUTOFF, SWS_MAX_REDUCE_CUTOFF].
160  */
161 static double est_filter_radius(const SwsFilterFunction *fun)
162 {
163  const double bound = fun->radius;
164  const double step = 1e-2;
165 
166  double radius = bound;
167  double prev = 0.0, fprev = 1.0; /* f(0) is always 1.0 */
168  double integral = 0.0;
169  for (double x = step; x < bound + step; x += step) {
170  const double fx = scaler_sample(fun, x);
171  integral += (fprev + fx) * step; /* trapezoidal rule (mirrored) */
172  double cutoff = SWS_MAX_REDUCE_CUTOFF * integral;
173  if ((fprev > cutoff && fx <= cutoff) || (fprev < -cutoff && fx >= -cutoff)) {
174  /* estimate crossing with secant method; note that we have to
175  * bias by the cutoff to find the actual cutoff radius */
176  double estimate = fx + (fx > fprev ? cutoff : -cutoff);
177  double root = x - estimate * (x - prev) / (fx - fprev);
178  radius = fmin(root, bound);
179  }
180  prev = x;
181  fprev = fx;
182  }
183 
184  return radius;
185 }
186 
187 int ff_sws_filter_generate(void *log, const SwsFilterParams *params,
189 {
190  SwsScaler scaler = params->scaler;
191  if (scaler >= SWS_SCALE_NB)
192  return AVERROR(EINVAL);
193 
194  if (scaler == SWS_SCALE_AUTO)
195  scaler = SWS_SCALE_BICUBIC;
196 
197  double virtual_size = params->virtual_size;
198  if (!virtual_size)
199  virtual_size = params->dst_size;
200 
201  const double ratio = virtual_size / params->src_size;
202  double stretch = 1.0;
203  if (ratio < 1.0 && scaler != SWS_SCALE_POINT) {
204  /* Widen filter for downscaling (anti-aliasing) */
205  stretch = 1.0 / ratio;
206  }
207 
208  if (scaler == SWS_SCALE_AREA) {
209  /**
210  * SWS_SCALE_AREA is a pseudo-filter that is equivalent to bilinear
211  * filtering for upscaling (since bilinear just evenly mixes samples
212  * according to the relative distance), and equivalent to (anti-aliased)
213  * point sampling for downscaling.
214  */
215  scaler = ratio >= 1.0 ? SWS_SCALE_BILINEAR : SWS_SCALE_POINT;
216  }
217 
218  SwsFilterFunction fun = filter_functions[scaler];
219  if (!fun.kernel)
220  return AVERROR(EINVAL);
221 
222  for (int i = 0; i < SWS_NUM_SCALER_PARAMS; i++) {
223  if (params->scaler_params[i] != SWS_PARAM_DEFAULT)
224  fun.params[i] = params->scaler_params[i];
225  }
226 
227  if (!validate_params(&fun, scaler)) {
228  av_log(log, AV_LOG_ERROR, "Invalid parameters for scaler %s: {%f, %f}\n",
229  fun.name, fun.params[0], fun.params[1]);
230  return AVERROR(EINVAL);
231  }
232 
233  if (fun.radius < 0.0) /* tunable width kernels like lanczos */
234  fun.radius = fun.params[0];
235 
236  double radius;
237  switch (scaler) {
238  case SWS_SCALE_POINT:
239  radius = 0.5;
240  break;
241  case SWS_SCALE_BILINEAR:
242  radius = 1.0 - SWS_MAX_REDUCE_CUTOFF;
243  break;
244  default:
245  /* Numerically estimate radius of nontrivial or parametric kernels */
246  radius = est_filter_radius(&fun);
247  break;
248  }
249  radius *= stretch;
250 
251  int filter_size = ceil(radius * 2.0);
252  filter_size = FFMIN(filter_size, params->src_size);
253  av_assert0(filter_size >= 1);
254  if (filter_size > SWS_FILTER_SIZE_MAX)
255  return AVERROR(ENOTSUP);
256 
259  if (!filter)
260  return AVERROR(ENOMEM);
261  memcpy(filter->name, fun.name, sizeof(filter->name));
262  filter->src_size = params->src_size;
263  filter->dst_size = params->dst_size;
264  filter->virtual_size = virtual_size;
265  filter->offset = params->offset;
266  filter->filter_size = filter_size;
267  if (filter->filter_size == 1)
268  filter->sum_positive = SWS_FILTER_SCALE;
269 
270  av_log(log, AV_LOG_DEBUG, "Generating %s filter with %d taps (radius = %f)\n",
271  filter->name, filter->filter_size, radius);
272 
273  filter->num_weights = (size_t) params->dst_size * filter->filter_size;
274  filter->weights = av_refstruct_allocz(filter->num_weights * sizeof(*filter->weights));
275  if (!filter->weights) {
277  return AVERROR(ENOMEM);
278  }
279 
280  filter->offsets = av_refstruct_allocz(params->dst_size * sizeof(*filter->offsets));
281  if (!filter->offsets) {
283  return AVERROR(ENOMEM);
284  }
285 
286  double *tmp = av_malloc(filter->filter_size * sizeof(*tmp));
287  if (!tmp) {
289  return AVERROR(ENOMEM);
290  }
291 
292  const double ratio_inv = 1.0 / ratio, stretch_inv = 1.0 / stretch;
293  for (int i = 0; i < params->dst_size; i++)
294  compute_row(filter, &fun, radius, ratio_inv, stretch_inv, i, tmp);
295  av_free(tmp);
296 
297  *out = filter;
298  return 0;
299 }
300 
301 /*
302  * Some of the filter code originally derives (via libplacebo/mpv) from Glumpy:
303  * # Copyright (c) 2009-2016 Nicolas P. Rougier. All rights reserved.
304  * # Distributed under the (new) BSD License.
305  * (https://github.com/glumpy/glumpy/blob/master/glumpy/library/build-spatial-filters.py)
306  *
307  * The math underlying each filter function was written from scratch, with
308  * some algorithms coming from a number of different sources, including:
309  * - https://en.wikipedia.org/wiki/Window_function
310  * - https://en.wikipedia.org/wiki/Jinc
311  * - http://vector-agg.cvs.sourceforge.net/viewvc/vector-agg/agg-2.5/include/agg_image_filters.h
312  * - Vapoursynth plugin fmtconv (WTFPL Licensed), which is based on
313  * dither plugin for avisynth from the same author:
314  * https://github.com/vapoursynth/fmtconv/tree/master/src/fmtc
315  * - Paul Heckbert's "zoom"
316  * - XBMC: ConvolutionKernels.cpp etc.
317  * - https://github.com/AviSynth/jinc-resize (only used to verify the math)
318  */
319 
320 av_unused static double box(double x, const double *params)
321 {
322  return 1.0;
323 }
324 
325 av_unused static double triangle(double x, const double *params)
326 {
327  return 1.0 - x;
328 }
329 
330 av_unused static double cosine(double x, const double *params)
331 {
332  return cos(x);
333 }
334 
335 av_unused static double hann(double x, const double *params)
336 {
337  return 0.5 + 0.5 * cos(M_PI * x);
338 }
339 
340 av_unused static double hamming(double x, const double *params)
341 {
342  return 0.54 + 0.46 * cos(M_PI * x);
343 }
344 
345 av_unused static double welch(double x, const double *params)
346 {
347  return 1.0 - x * x;
348 }
349 
350 av_unused static double bessel_i0(double x)
351 {
352  double s = 1.0;
353  double y = x * x / 4.0;
354  double t = y;
355  int i = 2;
356  while (t > 1e-12) {
357  s += t;
358  t *= y / (i * i);
359  i += 1;
360  }
361  return s;
362 }
363 
364 av_unused static double kaiser(double x, const double *params)
365 {
366  double alpha = fmax(params[0], 0.0);
367  double scale = bessel_i0(alpha);
368  return bessel_i0(alpha * sqrt(1.0 - x * x)) / scale;
369 }
370 
371 av_unused static double blackman(double x, const double *params)
372 {
373  double a = params[0];
374  double a0 = (1 - a) / 2.0, a1 = 1 / 2.0, a2 = a / 2.0;
375  x *= M_PI;
376  return a0 + a1 * cos(x) + a2 * cos(2 * x);
377 }
378 
379 av_unused static double bohman(double x, const double *params)
380 {
381  double pix = M_PI * x;
382  return (1.0 - x) * cos(pix) + sin(pix) / M_PI;
383 }
384 
385 av_unused static double gaussian(double x, const double *params)
386 {
387  return exp(-params[0] * x * x);
388 }
389 
390 av_unused static double quadratic(double x, const double *params)
391 {
392  if (x < 0.5) {
393  return 1.0 - 4.0/3.0 * (x * x);
394  } else {
395  return 2.0 / 3.0 * (x - 1.5) * (x - 1.5);
396  }
397 }
398 
399 av_unused static double sinc(double x, const double *params)
400 {
401  if (x < 1e-8)
402  return 1.0;
403  x *= M_PI;
404  return sin(x) / x;
405 }
406 
407 av_unused static double jinc(double x, const double *params)
408 {
409  if (x < 1e-8)
410  return 1.0;
411  x *= M_PI;
412  return 2.0 * j1(x) / x;
413 }
414 
415 av_unused static double sphinx(double x, const double *params)
416 {
417  if (x < 1e-8)
418  return 1.0;
419  x *= M_PI;
420  return 3.0 * (sin(x) - x * cos(x)) / (x * x * x);
421 }
422 
423 av_unused static double cubic(double x, const double *params)
424 {
425  const double b = params[0], c = params[1];
426  double p0 = 6.0 - 2.0 * b,
427  p2 = -18.0 + 12.0 * b + 6.0 * c,
428  p3 = 12.0 - 9.0 * b - 6.0 * c,
429  q0 = 8.0 * b + 24.0 * c,
430  q1 = -12.0 * b - 48.0 * c,
431  q2 = 6.0 * b + 30.0 * c,
432  q3 = -b - 6.0 * c;
433 
434  if (x < 1.0) {
435  return (p0 + x * x * (p2 + x * p3)) / p0;
436  } else {
437  return (q0 + x * (q1 + x * (q2 + x * q3))) / p0;
438  }
439 }
440 
441 static double spline_coeff(double a, double b, double c, double d, double x)
442 {
443  if (x <= 1.0) {
444  return ((d * x + c) * x + b) * x + a;
445  } else {
446  return spline_coeff(0.0,
447  b + 2.0 * c + 3.0 * d,
448  c + 3.0 * d,
449  -b - 3.0 * c - 6.0 * d,
450  x - 1.0);
451  }
452 }
453 
454 av_unused static double spline(double x, const double *params)
455 {
456  const double p = -2.196152422706632;
457  return spline_coeff(1.0, 0.0, p, -p - 1.0, x);
458 }
459 
461  [SWS_SCALE_BILINEAR] = { "bilinear", 1.0, triangle },
462  [SWS_SCALE_BICUBIC] = { "bicubic", 2.0, cubic, .params = { 0.0, 0.6 } },
463  [SWS_SCALE_POINT] = { "point", 0.5, box },
464  [SWS_SCALE_GAUSSIAN] = { "gaussian", 4.0, gaussian, .params = { 3.0 } },
465  [SWS_SCALE_SINC] = { "sinc", RADIUS_MAX, sinc },
466  [SWS_SCALE_LANCZOS] = { "lanczos", -1.0, sinc, sinc, .params = { 3.0 } },
467  [SWS_SCALE_SPLINE] = { "spline", RADIUS_MAX, spline },
468  /* SWS_SCALE_AREA is a pseudo-filter, see code above */
469 };
error
static void error(const char *err)
Definition: target_bsf_fuzzer.c:32
q1
static const uint8_t q1[256]
Definition: twofish.c:100
bohman
static av_unused double bohman(double x, const double *params)
Definition: filters.c:379
SWS_SCALE_AUTO
@ SWS_SCALE_AUTO
Definition: swscale.h:97
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
out
static FILE * out
Definition: movenc.c:55
SwsFilterParams::src_size
int src_size
The relative sizes of the input and output images.
Definition: filters.h:57
SWS_SCALE_BILINEAR
@ SWS_SCALE_BILINEAR
bilinear filtering
Definition: swscale.h:98
AVRefStructOpaque
RefStruct is an API for creating reference-counted objects with minimal overhead.
Definition: refstruct.h:58
int64_t
long long int64_t
Definition: coverity.c:34
RADIUS_MAX
#define RADIUS_MAX
Definition: filters.c:35
normalize.log
log
Definition: normalize.py:21
step
trying all byte sequences megabyte in length and selecting the best looking sequence will yield cases to try But a word about which is also called distortion Distortion can be quantified by almost any quality measurement one chooses the sum of squared differences is used but more complex methods that consider psychovisual effects can be used as well It makes no difference in this discussion First step
Definition: rate_distortion.txt:58
SwsFilterWeights
Represents a computed filter kernel.
Definition: filters.h:85
b
#define b
Definition: input.c:43
base
uint8_t base
Definition: vp3data.h:128
filter
void(* filter)(uint8_t *src, int stride, int qscale)
Definition: h263dsp.c:29
SwsFilterFunction::params
double params[SWS_NUM_SCALER_PARAMS]
Definition: filters.c:45
SwsFilterParams
Definition: filters.h:45
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
gaussian
static av_unused double gaussian(double x, const double *params)
Definition: filters.c:385
pix
enum AVPixelFormat pix
Definition: ohcodec.c:55
SwsFilterParams::virtual_size
double virtual_size
The virtual output size.
Definition: filters.h:72
ff_sws_filter_generate
int ff_sws_filter_generate(void *log, const SwsFilterParams *params, SwsFilterWeights **out)
Generate a filter kernel for the given parameters.
Definition: filters.c:187
welch
static av_unused double welch(double x, const double *params)
Definition: filters.c:345
SwsFilterParams::dst_size
int dst_size
Definition: filters.h:58
a2
static double a2(void *priv, double x, double y)
Definition: vf_xfade.c:2030
filter_functions
static const SwsFilterFunction filter_functions[SWS_SCALE_NB]
Definition: filters.c:48
av_unused
#define av_unused
Definition: attributes.h:164
av_refstruct_allocz
static void * av_refstruct_allocz(size_t size)
Equivalent to av_refstruct_alloc_ext(size, 0, NULL, NULL)
Definition: refstruct.h:105
SWS_SCALE_BICUBIC
@ SWS_SCALE_BICUBIC
2-tap cubic BC-spline
Definition: swscale.h:99
avassert.h
ceil
static __device__ float ceil(float a)
Definition: cuda_runtime.h:176
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:210
SWS_MAX_REDUCE_CUTOFF
#define SWS_MAX_REDUCE_CUTOFF
Filter kernel cut-off value.
Definition: swscale.h:449
s
#define s(width, name)
Definition: cbs_vp9.c:198
scaler_sample
static double scaler_sample(const SwsFilterFunction *f, double x)
Definition: filters.c:50
SwsFilterFunction::kernel
SwsFilterKernel kernel
Definition: filters.c:43
SwsFilterParams::offset
double offset
The sample offset, in units of input pixels.
Definition: filters.h:79
SWS_SCALE_LANCZOS
@ SWS_SCALE_LANCZOS
3-tap sinc/sinc
Definition: swscale.h:104
SWS_FILTER_SCALE
@ SWS_FILTER_SCALE
14-bit coefficients are picked to fit comfortably within int16_t for efficient SIMD processing (e....
Definition: filters.h:40
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:42
av_refstruct_alloc_ext
static void * av_refstruct_alloc_ext(size_t size, unsigned flags, void *opaque, void(*free_cb)(AVRefStructOpaque opaque, void *obj))
A wrapper around av_refstruct_alloc_ext_c() for the common case of a non-const qualified opaque.
Definition: refstruct.h:94
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:231
bessel_i0
static av_unused double bessel_i0(double x)
Definition: filters.c:350
hamming
static av_unused double hamming(double x, const double *params)
Definition: filters.c:340
kaiser
static av_unused double kaiser(double x, const double *params)
Definition: filters.c:364
q0
static const uint8_t q0[256]
Definition: twofish.c:81
tmp
static uint8_t tmp[40]
Definition: aes_ctr.c:52
SwsFilterFunction::window
SwsFilterKernel window
Definition: filters.c:44
SwsFilterFunction
Definition: filters.c:40
fabs
static __device__ float fabs(float a)
Definition: cuda_runtime.h:182
NULL
#define NULL
Definition: coverity.c:32
filters.h
double
double
Definition: af_crystalizer.c:132
SwsScaler
SwsScaler
Definition: swscale.h:96
est_filter_radius
static double est_filter_radius(const SwsFilterFunction *fun)
Numerically estimate the last intersection between the function value and the cutoff domain [-SWS_MAX...
Definition: filters.c:161
attributes.h
triangle
static av_unused double triangle(double x, const double *params)
Definition: filters.c:325
exp
int8_t exp
Definition: eval.c:76
SwsFilterFunction::name
char name[16]
Definition: filters.c:41
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
SWS_SCALE_SINC
@ SWS_SCALE_SINC
unwindowed sinc
Definition: swscale.h:103
SWS_PARAM_DEFAULT
#define SWS_PARAM_DEFAULT
Definition: swscale.h:458
cosine
static av_unused double cosine(double x, const double *params)
Definition: filters.c:330
f
f
Definition: af_crystalizer.c:122
hann
static av_unused double hann(double x, const double *params)
Definition: filters.c:335
jinc
static av_unused double jinc(double x, const double *params)
Definition: filters.c:407
SwsFilterFunction::radius
double radius
Definition: filters.c:42
i
#define i(width, name, range_min, range_max)
Definition: cbs_h264.c:63
fmin
double fmin(double, double)
a
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
Definition: undefined.txt:41
a0
static double a0(void *priv, double x, double y)
Definition: vf_xfade.c:2028
offset
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf offset
Definition: writing_filters.txt:86
cubic
static av_unused double cubic(double x, const double *params)
Definition: filters.c:423
M_PI
#define M_PI
Definition: mathematics.h:67
quadratic
static av_unused double quadratic(double x, const double *params)
Definition: filters.c:390
av_refstruct_unref
void av_refstruct_unref(void *objp)
Decrement the reference count of the underlying object and automatically free the object if there are...
Definition: refstruct.c:120
sws_filter_free
static void sws_filter_free(AVRefStructOpaque opaque, void *obj)
Definition: filters.c:136
SWS_SCALE_POINT
@ SWS_SCALE_POINT
nearest neighbor (point sampling)
Definition: swscale.h:100
box
static av_unused double box(double x, const double *params)
Definition: filters.c:320
av_malloc
#define av_malloc(s)
Definition: ops_asmgen.c:44
round
static av_always_inline av_const double round(double x)
Definition: libm.h:446
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
SwsFilterParams::scaler_params
double scaler_params[SWS_NUM_SCALER_PARAMS]
Definition: filters.h:50
SWS_SCALE_GAUSSIAN
@ SWS_SCALE_GAUSSIAN
2-tap gaussian approximation
Definition: swscale.h:102
bound
static double bound(const double threshold, const double val)
Definition: af_dynaudnorm.c:413
validate_params
static bool validate_params(const SwsFilterFunction *fun, SwsScaler scaler)
Definition: filters.c:143
pos
unsigned int pos
Definition: spdifenc.c:414
blackman
static av_unused double blackman(double x, const double *params)
Definition: filters.c:371
fmax
double fmax(double, double)
SWS_NUM_SCALER_PARAMS
#define SWS_NUM_SCALER_PARAMS
Extra parameters for fine-tuning certain scalers.
Definition: swscale.h:247
SWS_SCALE_NB
@ SWS_SCALE_NB
not part of the ABI
Definition: swscale.h:106
SWS_SCALE_SPLINE
@ SWS_SCALE_SPLINE
unwindowned natural cubic spline
Definition: swscale.h:105
Windows::Graphics::DirectX::Direct3D11::p
IDirect3DDxgiInterfaceAccess _COM_Outptr_ void ** p
Definition: vsrc_gfxcapture_winrt.hpp:53
mem.h
w
uint8_t w
Definition: llvidencdsp.c:39
SWS_FILTER_SIZE_MAX
@ SWS_FILTER_SIZE_MAX
Definition: filters.h:41
av_free
#define av_free(p)
Definition: tableprint_vlc.h:34
scale
static void scale(int *out, const int *in, const int w, const int h, const int shift)
Definition: intra.c:278
alpha
static const int16_t alpha[]
Definition: ilbcdata.h:55
spline_coeff
static double spline_coeff(double a, double b, double c, double d, double x)
Definition: filters.c:441
sinc
static av_unused double sinc(double x, const double *params)
Definition: filters.c:399
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
SWS_SCALE_AREA
@ SWS_SCALE_AREA
area averaging
Definition: swscale.h:101
sphinx
static av_unused double sphinx(double x, const double *params)
Definition: filters.c:415
SwsFilterKernel
double(* SwsFilterKernel)(double x, const double *params)
Definition: filters.c:38
a1
static double a1(void *priv, double x, double y)
Definition: vf_xfade.c:2029
SwsFilterParams::scaler
SwsScaler scaler
The filter kernel and parameters to use.
Definition: filters.h:49
spline
static av_unused double spline(double x, const double *params)
Definition: filters.c:454
compute_row
static void compute_row(SwsFilterWeights *f, const SwsFilterFunction *fun, double radius, double ratio_inv, double stretch_inv, int dst_pos, double *tmp)
Definition: filters.c:62