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;
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 static double filter_radius(const SwsFilterFunction *fun)
158 {
159  const double bound = fun->radius;
160  const double step = 1e-2;
161 
162  double radius = bound;
163  double prev = 0.0, fprev = 1.0; /* f(0) is always 1.0 */
164  double integral = 0.0;
165  for (double x = step; x < bound + step; x += step) {
166  const double fx = scaler_sample(fun, x);
167  integral += (fprev + fx) * step; /* trapezoidal rule (mirrored) */
168  double cutoff = SWS_MAX_REDUCE_CUTOFF * integral;
169  if ((fprev > cutoff && fx <= cutoff) || (fprev < -cutoff && fx >= -cutoff)) {
170  /* estimate crossing with secant method; note that we have to
171  * bias by the cutoff to find the actual cutoff radius */
172  double estimate = fx + (fx > fprev ? cutoff : -cutoff);
173  double root = x - estimate * (x - prev) / (fx - fprev);
174  radius = fmin(root, bound);
175  }
176  prev = x;
177  fprev = fx;
178  }
179 
180  return radius;
181 }
182 
183 int ff_sws_filter_generate(void *log, const SwsFilterParams *params,
185 {
186  SwsScaler scaler = params->scaler;
187  if (scaler >= SWS_SCALE_NB)
188  return AVERROR(EINVAL);
189 
190  if (scaler == SWS_SCALE_AUTO)
191  scaler = SWS_SCALE_BICUBIC;
192 
193  const double ratio = (double) params->dst_size / params->src_size;
194  double stretch = 1.0;
195  if (ratio < 1.0 && scaler != SWS_SCALE_POINT) {
196  /* Widen filter for downscaling (anti-aliasing) */
197  stretch = 1.0 / ratio;
198  }
199 
200  if (scaler == SWS_SCALE_AREA) {
201  /**
202  * SWS_SCALE_AREA is a pseudo-filter that is equivalent to bilinear
203  * filtering for upscaling (since bilinear just evenly mixes samples
204  * according to the relative distance), and equivalent to (anti-aliased)
205  * point sampling for downscaling.
206  */
207  scaler = ratio >= 1.0 ? SWS_SCALE_BILINEAR : SWS_SCALE_POINT;
208  }
209 
210  SwsFilterFunction fun = filter_functions[scaler];
211  if (!fun.kernel)
212  return AVERROR(EINVAL);
213 
214  for (int i = 0; i < SWS_NUM_SCALER_PARAMS; i++) {
215  if (params->scaler_params[i] != SWS_PARAM_DEFAULT)
216  fun.params[i] = params->scaler_params[i];
217  }
218 
219  if (!validate_params(&fun, scaler)) {
220  av_log(log, AV_LOG_ERROR, "Invalid parameters for scaler %s: {%f, %f}\n",
221  fun.name, fun.params[0], fun.params[1]);
222  return AVERROR(EINVAL);
223  }
224 
225  if (fun.radius < 0.0) /* tunable width kernels like lanczos */
226  fun.radius = fun.params[0];
227 
228  const double radius = filter_radius(&fun) * stretch;
229  int filter_size = ceil(radius * 2.0);
230  filter_size = FFMIN(filter_size, params->src_size);
231  av_assert0(filter_size >= 1);
232  if (filter_size > SWS_FILTER_SIZE_MAX)
233  return AVERROR(ENOTSUP);
234 
237  if (!filter)
238  return AVERROR(ENOMEM);
239  memcpy(filter->name, fun.name, sizeof(filter->name));
240  filter->src_size = params->src_size;
241  filter->dst_size = params->dst_size;
242  filter->filter_size = filter_size;
243  if (filter->filter_size == 1)
244  filter->sum_positive = SWS_FILTER_SCALE;
245 
246  av_log(log, AV_LOG_DEBUG, "Generating %s filter with %d taps (radius = %f)\n",
247  filter->name, filter->filter_size, radius);
248 
249  filter->num_weights = (size_t) params->dst_size * filter->filter_size;
250  filter->weights = av_refstruct_allocz(filter->num_weights * sizeof(*filter->weights));
251  if (!filter->weights) {
253  return AVERROR(ENOMEM);
254  }
255 
256  filter->offsets = av_refstruct_allocz(params->dst_size * sizeof(*filter->offsets));
257  if (!filter->offsets) {
259  return AVERROR(ENOMEM);
260  }
261 
262  double *tmp = av_malloc(filter->filter_size * sizeof(*tmp));
263  if (!tmp) {
265  return AVERROR(ENOMEM);
266  }
267 
268  const double ratio_inv = 1.0 / ratio, stretch_inv = 1.0 / stretch;
269  for (int i = 0; i < params->dst_size; i++)
270  compute_row(filter, &fun, radius, ratio_inv, stretch_inv, i, tmp);
271  av_free(tmp);
272 
273  *out = filter;
274  return 0;
275 }
276 
277 /*
278  * Some of the filter code originally derives (via libplacebo/mpv) from Glumpy:
279  * # Copyright (c) 2009-2016 Nicolas P. Rougier. All rights reserved.
280  * # Distributed under the (new) BSD License.
281  * (https://github.com/glumpy/glumpy/blob/master/glumpy/library/build-spatial-filters.py)
282  *
283  * The math underlying each filter function was written from scratch, with
284  * some algorithms coming from a number of different sources, including:
285  * - https://en.wikipedia.org/wiki/Window_function
286  * - https://en.wikipedia.org/wiki/Jinc
287  * - http://vector-agg.cvs.sourceforge.net/viewvc/vector-agg/agg-2.5/include/agg_image_filters.h
288  * - Vapoursynth plugin fmtconv (WTFPL Licensed), which is based on
289  * dither plugin for avisynth from the same author:
290  * https://github.com/vapoursynth/fmtconv/tree/master/src/fmtc
291  * - Paul Heckbert's "zoom"
292  * - XBMC: ConvolutionKernels.cpp etc.
293  * - https://github.com/AviSynth/jinc-resize (only used to verify the math)
294  */
295 
296 av_unused static double box(double x, const double *params)
297 {
298  return 1.0;
299 }
300 
301 av_unused static double triangle(double x, const double *params)
302 {
303  return 1.0 - x;
304 }
305 
306 av_unused static double cosine(double x, const double *params)
307 {
308  return cos(x);
309 }
310 
311 av_unused static double hann(double x, const double *params)
312 {
313  return 0.5 + 0.5 * cos(M_PI * x);
314 }
315 
316 av_unused static double hamming(double x, const double *params)
317 {
318  return 0.54 + 0.46 * cos(M_PI * x);
319 }
320 
321 av_unused static double welch(double x, const double *params)
322 {
323  return 1.0 - x * x;
324 }
325 
326 av_unused static double bessel_i0(double x)
327 {
328  double s = 1.0;
329  double y = x * x / 4.0;
330  double t = y;
331  int i = 2;
332  while (t > 1e-12) {
333  s += t;
334  t *= y / (i * i);
335  i += 1;
336  }
337  return s;
338 }
339 
340 av_unused static double kaiser(double x, const double *params)
341 {
342  double alpha = fmax(params[0], 0.0);
343  double scale = bessel_i0(alpha);
344  return bessel_i0(alpha * sqrt(1.0 - x * x)) / scale;
345 }
346 
347 av_unused static double blackman(double x, const double *params)
348 {
349  double a = params[0];
350  double a0 = (1 - a) / 2.0, a1 = 1 / 2.0, a2 = a / 2.0;
351  x *= M_PI;
352  return a0 + a1 * cos(x) + a2 * cos(2 * x);
353 }
354 
355 av_unused static double bohman(double x, const double *params)
356 {
357  double pix = M_PI * x;
358  return (1.0 - x) * cos(pix) + sin(pix) / M_PI;
359 }
360 
361 av_unused static double gaussian(double x, const double *params)
362 {
363  return exp(-params[0] * x * x);
364 }
365 
366 av_unused static double quadratic(double x, const double *params)
367 {
368  if (x < 0.5) {
369  return 1.0 - 4.0/3.0 * (x * x);
370  } else {
371  return 2.0 / 3.0 * (x - 1.5) * (x - 1.5);
372  }
373 }
374 
375 av_unused static double sinc(double x, const double *params)
376 {
377  if (x < 1e-8)
378  return 1.0;
379  x *= M_PI;
380  return sin(x) / x;
381 }
382 
383 av_unused static double jinc(double x, const double *params)
384 {
385  if (x < 1e-8)
386  return 1.0;
387  x *= M_PI;
388  return 2.0 * j1(x) / x;
389 }
390 
391 av_unused static double sphinx(double x, const double *params)
392 {
393  if (x < 1e-8)
394  return 1.0;
395  x *= M_PI;
396  return 3.0 * (sin(x) - x * cos(x)) / (x * x * x);
397 }
398 
399 av_unused static double cubic(double x, const double *params)
400 {
401  const double b = params[0], c = params[1];
402  double p0 = 6.0 - 2.0 * b,
403  p2 = -18.0 + 12.0 * b + 6.0 * c,
404  p3 = 12.0 - 9.0 * b - 6.0 * c,
405  q0 = 8.0 * b + 24.0 * c,
406  q1 = -12.0 * b - 48.0 * c,
407  q2 = 6.0 * b + 30.0 * c,
408  q3 = -b - 6.0 * c;
409 
410  if (x < 1.0) {
411  return (p0 + x * x * (p2 + x * p3)) / p0;
412  } else {
413  return (q0 + x * (q1 + x * (q2 + x * q3))) / p0;
414  }
415 }
416 
417 static double spline_coeff(double a, double b, double c, double d, double x)
418 {
419  if (x <= 1.0) {
420  return ((d * x + c) * x + b) * x + a;
421  } else {
422  return spline_coeff(0.0,
423  b + 2.0 * c + 3.0 * d,
424  c + 3.0 * d,
425  -b - 3.0 * c - 6.0 * d,
426  x - 1.0);
427  }
428 }
429 
430 av_unused static double spline(double x, const double *params)
431 {
432  const double p = -2.196152422706632;
433  return spline_coeff(1.0, 0.0, p, -p - 1.0, x);
434 }
435 
437  [SWS_SCALE_BILINEAR] = { "bilinear", 1.0, triangle },
438  [SWS_SCALE_BICUBIC] = { "bicubic", 2.0, cubic, .params = { 0.0, 0.6 } },
439  [SWS_SCALE_POINT] = { "point", 0.5, box },
440  [SWS_SCALE_GAUSSIAN] = { "gaussian", 4.0, gaussian, .params = { 3.0 } },
441  [SWS_SCALE_SINC] = { "sinc", RADIUS_MAX, sinc },
442  [SWS_SCALE_LANCZOS] = { "lanczos", -1.0, sinc, sinc, .params = { 3.0 } },
443  [SWS_SCALE_SPLINE] = { "spline", RADIUS_MAX, spline },
444  /* SWS_SCALE_AREA is a pseudo-filter, see code above */
445 };
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:355
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
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:64
b
#define b
Definition: input.c:42
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:361
pix
enum AVPixelFormat pix
Definition: ohcodec.c:55
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
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:183
welch
static av_unused double welch(double x, const double *params)
Definition: filters.c:321
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_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:414
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
SWS_SCALE_LANCZOS
@ SWS_SCALE_LANCZOS
3-tap sinc/sinc
Definition: swscale.h:104
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:326
hamming
static av_unused double hamming(double x, const double *params)
Definition: filters.c:316
kaiser
static av_unused double kaiser(double x, const double *params)
Definition: filters.c:340
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
if
if(ret)
Definition: filter_design.txt:179
SWS_FILTER_SIZE_MAX
@ SWS_FILTER_SIZE_MAX
Definition: filters.h:41
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
triangle
static av_unused double triangle(double x, const double *params)
Definition: filters.c:301
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:423
cosine
static av_unused double cosine(double x, const double *params)
Definition: filters.c:306
f
f
Definition: af_crystalizer.c:122
hann
static av_unused double hann(double x, const double *params)
Definition: filters.c:311
jinc
static av_unused double jinc(double x, const double *params)
Definition: filters.c:383
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
attributes.h
cubic
static av_unused double cubic(double x, const double *params)
Definition: filters.c:399
M_PI
#define M_PI
Definition: mathematics.h:67
quadratic
static av_unused double quadratic(double x, const double *params)
Definition: filters.c:366
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:296
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
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:347
fmax
double fmax(double, double)
SWS_NUM_SCALER_PARAMS
#define SWS_NUM_SCALER_PARAMS
Extra parameters for fine-tuning certain scalers.
Definition: swscale.h:224
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
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:157
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:417
sinc
static av_unused double sinc(double x, const double *params)
Definition: filters.c:375
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:391
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:430
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