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