Go to the documentation of this file.
29 #if IS_FLOAT && BIT_DEPTH == 32
30 # define PIXEL_TYPE SWS_PIXEL_F32
31 # define pixel_t float
32 # define inter_t float
36 # define PIXEL_MAX 0xFFFFFFFFu
37 # define PIXEL_SWAP av_bswap32
38 # define pixel_t uint32_t
39 # define inter_t int64_t
43 # define PIXEL_MAX 0xFFFFu
44 # define PIXEL_SWAP av_bswap16
45 # define pixel_t uint16_t
46 # define inter_t int64_t
50 # define PIXEL_MAX 0xFFu
51 # define pixel_t uint8_t
52 # define inter_t int32_t
56 # error Invalid BIT_DEPTH
83 const int elems =
W ? 4 :
Z ? 3 :
Y ? 2 : 1;
87 if (
X) x[
i] = in0[elems *
i + 0];
88 if (
Y) y[
i] = in0[elems *
i + 1];
89 if (
Z) z[
i] = in0[elems *
i + 2];
90 if (
W)
w[
i] = in0[elems *
i + 3];
101 if (
X) out0[
i] = x[
i];
102 if (
Y) out1[
i] = y[
i];
103 if (
Z) out2[
i] = z[
i];
104 if (
W) out3[
i] =
w[
i];
115 const int elems =
W ? 4 :
Z ? 3 :
Y ? 2 : 1;
119 if (
X) out0[elems *
i + 0] = x[
i];
120 if (
Y) out0[elems *
i + 1] = y[
i];
121 if (
Z) out0[elems *
i + 2] = z[
i];
122 if (
W) out0[elems *
i + 3] =
w[
i];
137 x[
i + 0] = (
val >> 7) & 1;
138 x[
i + 1] = (
val >> 6) & 1;
139 x[
i + 2] = (
val >> 5) & 1;
140 x[
i + 3] = (
val >> 4) & 1;
141 x[
i + 4] = (
val >> 3) & 1;
142 x[
i + 5] = (
val >> 2) & 1;
143 x[
i + 6] = (
val >> 1) & 1;
144 x[
i + 7] = (
val >> 0) & 1;
159 x[
i + 1] =
val & 0xF;
190 out0[
i >> 3] = x[
i + 0] << 7 |
209 out0[
i >> 1] = x[
i] << 4 | x[
i + 1];
246 static_assert(
sizeof(
out->priv.ptr) <=
sizeof(
int32_t[2]),
247 ">8 byte pointers not supported");
254 for (
int i = 0;
i <
filter->num_weights;
i++)
268 const float *restrict
weights = impl->priv.ptr;
269 const int filter_size = impl->priv.i32[2];
270 weights += filter_size * iter->y;
273 if (
X) memset(&
xs.f32, 0,
sizeof(
xs.f32));
274 if (
Y) memset(&ys.
f32, 0,
sizeof(ys.
f32));
275 if (
Z) memset(&zs.
f32, 0,
sizeof(zs.
f32));
276 if (
W) memset(&ws.
f32, 0,
sizeof(ws.
f32));
278 for (
int j = 0; j < filter_size; j++) {
320 const int *restrict
weights = impl->priv.ptr;
321 const int filter_size = impl->priv.i32[2];
323 const int xpos = iter->x;
324 weights += filter_size * iter->x;
334 inter_t sx = 0, sy = 0, sz = 0, sw = 0;
335 for (
int j = 0; j < filter_size; j++) {
337 if (
X) sx +=
weight * start0[j];
338 if (
Y) sy +=
weight * start1[j];
339 if (
Z) sz +=
weight * start2[j];
340 if (
W) sw +=
weight * start3[j];
364 int8_t d0, int8_t d1, int8_t d2, int8_t d3, int8_t d4, int8_t d5,
365 int8_t s0, int8_t s1, int8_t s2, int8_t s3, int8_t s4, int8_t s5)
371 for (
int n = 0; n < num_moves; n++)
372 ptr[
dst[n] + 1] = ptr[
src[n] + 1];
384 int8_t d0, int8_t d1, int8_t d2, int8_t d3, int8_t d4, int8_t d5,
385 int8_t s0, int8_t s1, int8_t s2, int8_t s3, int8_t s4, int8_t s5)
392 memcpy(&
data[1].
px, x, block_size);
393 memcpy(&
data[2].
px, y, block_size);
394 memcpy(&
data[3].
px, z, block_size);
395 memcpy(&
data[4].
px,
w, block_size);
397 for (
int n = 0; n < num_moves; n++)
400 memcpy(x, &
data[1].
px, block_size);
401 memcpy(y, &
data[2].
px, block_size);
402 memcpy(z, &
data[3].
px, block_size);
403 memcpy(
w, &
data[4].
px, block_size);
417 #define DECL_CAST(DST, dst) \
418 DECL_FUNC(to_##dst, const SwsCompMask mask) \
420 block_t xx, yy, zz, ww; \
423 for (int i = 0; i < SWS_BLOCK_SIZE; i++) { \
424 if (X) xx.dst[i] = x[i]; \
425 if (Y) yy.dst[i] = y[i]; \
426 if (Z) zz.dst[i] = z[i]; \
427 if (W) ww.dst[i] = w[i]; \
430 CONTINUE(&xx, &yy, &zz, &ww); \
433 SWS_FOR(PX, TO_##DST, DECL_IMPL, to_##dst) \
434 SWS_FOR_STRUCT(PX, TO_##DST, DECL_ENTRY)
450 if (
X) x[
i] <<= amount;
451 if (
Y) y[
i] <<= amount;
452 if (
Z) z[
i] <<= amount;
453 if (
W)
w[
i] <<= amount;
463 if (
X) x[
i] >>= amount;
464 if (
Y) y[
i] >>= amount;
465 if (
Z) z[
i] >>= amount;
466 if (
W)
w[
i] >>= amount;
484 if (
X) x[
i] = PIXEL_SWAP(x[
i]);
485 if (
Y) y[
i] = PIXEL_SWAP(y[
i]);
486 if (
Z) z[
i] = PIXEL_SWAP(z[
i]);
487 if (
W)
w[
i] = PIXEL_SWAP(
w[
i]);
519 if (
X) x16.
u16[
i] = x[
i] << 8 | x[
i];
520 if (
Y) y16.
u16[
i] = y[
i] << 8 | y[
i];
521 if (
Z) z16.
u16[
i] = z[
i] << 8 | z[
i];
534 if (
X) x32.
u32[
i] = (uint32_t) x[
i] << 24 | x[
i] << 16 | x[
i] << 8 | x[
i];
535 if (
Y) y32.
u32[
i] = (uint32_t) y[
i] << 24 | y[
i] << 16 | y[
i] << 8 | y[
i];
536 if (
Z) z32.
u32[
i] = (uint32_t) z[
i] << 24 | z[
i] << 16 | z[
i] << 8 | z[
i];
537 if (
W) w32.
u32[
i] = (uint32_t)
w[
i] << 24 |
w[
i] << 16 |
w[
i] << 8 |
w[
i];
557 const uint8_t bx,
const uint8_t by,
558 const uint8_t bz,
const uint8_t bw)
560 const uint8_t sx = bw + bz + by;
561 const uint8_t sy = bw + bz;
562 const uint8_t sz = bw;
563 const uint8_t sw = 0;
568 const pixel_t mw = (1 << bw) - 1;
573 if (
X) x[
i] = (
val >> sx) &
mx;
574 if (
Y) y[
i] = (
val >> sy) &
my;
575 if (
Z) z[
i] = (
val >> sz) &
mz;
576 if (
W)
w[
i] = (
val >> sw) & mw;
583 const uint8_t bx,
const uint8_t by,
584 const uint8_t bz,
const uint8_t bw)
586 const uint8_t sx = bw + bz + by;
587 const uint8_t sy = bw + bz;
588 const uint8_t sz = bw;
589 const uint8_t sw = 0;
594 if (
X)
val |= x[
i] << sx;
595 if (
Y)
val |= y[
i] << sy;
596 if (
Z)
val |= z[
i] << sz;
618 #define ONE(N) SWS_COMP_TEST(one, N)
619 #define ZERO(N) SWS_COMP_TEST(zero, N)
663 if (
X) x[
i] += impl->priv.px[0];
664 if (
Y) y[
i] += impl->priv.px[1];
665 if (
Z) z[
i] += impl->priv.px[2];
666 if (
W)
w[
i] += impl->priv.px[3];
676 if (
X) x[
i] =
FFMIN(x[
i], impl->priv.px[0]);
677 if (
Y) y[
i] =
FFMIN(y[
i], impl->priv.px[1]);
678 if (
Z) z[
i] =
FFMIN(z[
i], impl->priv.px[2]);
689 if (
X) x[
i] =
FFMAX(x[
i], impl->priv.px[0]);
690 if (
Y) y[
i] =
FFMAX(y[
i], impl->priv.px[1]);
691 if (
Z) z[
i] =
FFMAX(z[
i], impl->priv.px[2]);
734 for (
int y = 0; y <
height; y++) {
736 for (
int x = 0; x <
size; x++)
739 row[x] = row[x %
size];
746 const uint8_t off0,
const uint8_t off1,
747 const uint8_t off2,
const uint8_t off3,
748 const uint8_t size_log2)
750 const int size = 1 << size_log2;
764 if (
X) x[
i] += row0[
i];
765 if (
Y) y[
i] += row1[
i];
766 if (
Z) z[
i] += row2[
i];
767 if (
W)
w[
i] += row3[
i];
791 for (
int i = 0;
i < 4;
i++) {
792 for (
int j = 0; j < 4; j++)
810 const fn(LinCoeffs)
c = *(
const fn(LinCoeffs) *) impl->priv.ptr;
819 #define LIN_VAL(I, J, val) \
820 ((one & SWS_MASK(I, J)) ? (val) : c.m[I][J] * (val))
822 #define LIN_ROW(I, var) do { \
823 var[i] = (zero & SWS_MASK(I, 4)) ? 0 : c.k[I]; \
824 if (!(zero & SWS_MASK(I, 0))) var[i] += LIN_VAL(I, 0, xx); \
825 if (!(zero & SWS_MASK(I, 1))) var[i] += LIN_VAL(I, 1, yy); \
826 if (!(zero & SWS_MASK(I, 2))) var[i] += LIN_VAL(I, 2, zz); \
827 if (!(zero & SWS_MASK(I, 3))) var[i] += LIN_VAL(I, 3, ww); \
#define DECL_IMPL_WRITE(...)
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
float f32[SWS_BLOCK_SIZE]
#define DECL_ENTRY(SETUP, NAME,...)
Represents a computed filter kernel.
static void permute(int16_t dst[64], const int16_t src[64], enum idct_permutation_type perm_type)
static int linear(InterplayACMContext *s, unsigned ind, unsigned col)
void(* filter)(uint8_t *src, int stride, int qscale)
static void ff_op_priv_unref(SwsOpPriv *priv)
static int setup_linear(const SwsImplParams *params, SwsImplResult *out)
void * av_memdup(const void *p, size_t size)
Duplicate a buffer with av_malloc().
static int setup_dither(const SwsImplParams *params, SwsImplResult *out)
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t mx
DECL_WRITE(write_planar, const SwsCompMask mask)
const h264_weight_func weight
static double val(void *priv, double ch)
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 type
#define SWS_COMP_ELEMS(N)
#define SWS_FOR(TYPE, UOP, MACRO,...)
@ SWS_FILTER_SCALE
14-bit coefficients are picked to fit comfortably within int16_t for efficient SIMD processing (e....
#define SWS_FOR_STRUCT(TYPE, UOP, MACRO,...)
static const uint16_t dither[8][8]
uint8_t SwsCompMask
Bit-mask of components.
SwsAArch64OpImplParams params
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t my
static unsigned int BS_FUNC() read_bit(BSCTX *bc)
Return one bit from the buffer.
Copyright (C) 2026 Niklas Haas.
#define xs(width, name, var, subs,...)
#define DECL_IMPL(FUNC, NAME, TYPE, UOP,...)
#define SWS_BLOCK_SIZE
Copyright (C) 2026 Niklas Haas.
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
int ff_sws_setup_vec4(const SwsImplParams *params, SwsImplResult *out)
static void copy(const float *p1, float *p2, const int length)
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
#define i(width, name, range_min, range_max)
static double mz(int i, double w0, double r, double alpha)
void * av_refstruct_ref(void *obj)
Create a new reference to an object managed via this API, i.e.
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
static int zero(InterplayACMContext *s, unsigned ind, unsigned col)
DECL_FUNC(permute, const SwsCompMask mask, int num_moves, int8_t d0, int8_t d1, int8_t d2, int8_t d3, int8_t d4, int8_t d5, int8_t s0, int8_t s1, int8_t s2, int8_t s3, int8_t s4, int8_t s5)
#define av_assert2(cond)
assert() equivalent, that does lie in speed critical code.
static int unpack(const uint8_t *src, const uint8_t *src_end, uint8_t *dst, int width, int height)
Unpack buffer.
int32_t * in_offset_x
Pixel offset map; for horizontal scaling, in bytes.
static const int weights[]
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 default value
void * av_calloc(size_t nmemb, size_t size)
static void ff_op_priv_free(SwsOpPriv *priv)
#define bump_ptr(ptr, bump)
DECL_SETUP(setup_filter_v, params, out)
#define DECL_CAST(DST, dst)
uint32_t u32[SWS_BLOCK_SIZE]
int ff_sws_setup_scalar(const SwsImplParams *params, SwsImplResult *out)
uint16_t u16[SWS_BLOCK_SIZE]
static void scale(int *out, const int *in, const int w, const int h, const int shift)
static int setup_filter_v(const SwsImplParams *params, SwsImplResult *out)
DECL_READ(read_planar, const SwsCompMask mask)
int ff_sws_dither_height(const SwsDitherUOp *dither)
Computes (1 << size_log2) + MAX(y_offset).
#define DECL_IMPL_READ(...)
static int setup_filter_h(const SwsImplParams *params, SwsImplResult *out)