Go to the documentation of this file.
24 # error Should only be included from ops_tmpl_*.c!
27 #define WRAP_CONVERT_UINT(N) \
28 DECL_PATTERN(convert_uint##N) \
30 u##N##block_t xu, yu, zu, wu; \
33 for (int i = 0; i < SWS_BLOCK_SIZE; i++) { \
44 CONTINUE(xu, yu, zu, wu); \
47 WRAP_COMMON_PATTERNS(convert_uint##N, \
48 .op = SWS_OP_CONVERT, \
49 .convert.to = SWS_PIXEL_U##N, \
60 #if BIT_DEPTH != 32 || defined(IS_FLOAT)
69 x[
i] = impl->priv.px[0];
71 y[
i] = impl->priv.px[1];
73 z[
i] = impl->priv.px[2];
75 w[
i] = impl->priv.px[3];
81 #define WRAP_CLEAR(X, Y, Z, W) \
82 DECL_IMPL(clear, clear##_##X##Y##Z##W, X, Y, Z, W) \
84 DECL_ENTRY(clear##_##X##Y##Z##W, SWS_COMP_ALL, \
85 .setup = ff_sws_setup_clear, \
87 .clear.mask = SWS_COMP_MASK(X, Y, Z, W), \
109 x[
i] =
FFMIN(x[
i], impl->priv.px[0]);
111 y[
i] =
FFMIN(y[
i], impl->priv.px[1]);
113 z[
i] =
FFMIN(z[
i], impl->priv.px[2]);
126 x[
i] =
FFMAX(x[
i], impl->priv.px[0]);
128 y[
i] =
FFMAX(y[
i], impl->priv.px[1]);
130 z[
i] =
FFMAX(z[
i], impl->priv.px[2]);
178 static_assert(
sizeof(
out->priv.ptr) <=
sizeof(
int32_t[2]),
179 ">8 byte pointers not supported");
186 for (
int i = 0;
i <
filter->num_weights;
i++)
199 const float *restrict
weights = impl->priv.ptr;
200 const int filter_size = impl->priv.i32[2];
201 weights += filter_size * iter->y;
204 memset(
xs, 0,
sizeof(
xs));
206 memset(ys, 0,
sizeof(ys));
208 memset(zs, 0,
sizeof(zs));
210 memset(ws, 0,
sizeof(ws));
212 for (
int j = 0; j < filter_size; j++) {
235 for (
int i = 0;
i < elems;
i++)
254 const int *restrict
weights = impl->priv.ptr;
255 const int filter_size = impl->priv.i32[2];
257 const int xpos = iter->x;
258 weights += filter_size * iter->x;
268 inter_t sx = 0, sy = 0, sz = 0, sw = 0;
269 for (
int j = 0; j < filter_size; j++) {
294 #define WRAP_FILTER(FUNC, DIR, ELEMS, SUFFIX) \
295 static av_flatten void fn(FUNC##ELEMS##SUFFIX)(SwsOpIter *restrict iter, \
296 const SwsOpImpl *restrict impl, \
297 void *restrict x, void *restrict y,\
298 void *restrict z, void *restrict w)\
300 CALL_READ(FUNC##SUFFIX, ELEMS); \
303 DECL_ENTRY(FUNC##ELEMS##SUFFIX, SWS_COMP_ELEMS(ELEMS), \
305 .setup = fn(setup_filter##SUFFIX), \
307 .rw.filter = SWS_OP_FILTER_##DIR, \
321 const
int bx_start, const
int y_start,
322 int bx_end,
int y_end)
331 for (
int i = 0;
i < 4;
i++) {
332 iter->
in[
i] = (uintptr_t) exec->in[
i];
333 iter->
out[
i] = (uintptr_t) exec->out[
i];
336 for (iter->
y = y_start; iter->
y < y_end; iter->
y++) {
342 const int y_bump = exec->in_bump_y ? exec->in_bump_y[iter->
y] : 0;
343 for (
int i = 0;
i < 4;
i++) {
344 iter->
in[
i] += exec->in_bump[
i] + y_bump * exec->in_stride[
i];
345 iter->
out[
i] += exec->out_bump[
i];
#define WRAP_CLEAR(X, Y, Z, W)
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 f32block_t[SWS_BLOCK_SIZE]
int ff_sws_setup_scale(const SwsImplParams *params, SwsImplResult *out)
Represents a computed filter kernel.
#define CONTINUE(X, Y, Z, W)
void(* filter)(uint8_t *src, int stride, int qscale)
Copyright (C) 2025 Niklas Haas.
static void ff_op_priv_unref(SwsOpPriv *priv)
#define WRAP_CONVERT_UINT(N)
Copyright (C) 2025 Niklas Haas.
const h264_weight_func weight
static int op(uint8_t **dst, const uint8_t *dst_end, GetByteContext *gb, int pixel, int count, int *x, int width, int linesize)
Perform decode operation.
DECL_READ(filter_v, const int elems)
uint32_t u32block_t[SWS_BLOCK_SIZE]
SwsOpImpl impl[SWS_MAX_OPS+1]
#define SWS_BLOCK_SIZE
Copyright (C) 2025 Niklas Haas.
Copyright (C) 2026 Niklas Haas.
#define bump_ptr(ptr, bump)
#define xs(width, name, var, subs,...)
Compiled "chain" of operations, which can be dispatched efficiently.
@ SWS_FILTER_SCALE
14-bit coefficients are picked to fit comfortably within int16_t for efficient SIMD processing (e....
int ff_sws_setup_clamp(const SwsImplParams *params, SwsImplResult *out)
#define i(width, name, range_min, range_max)
#define WRAP_FILTER(FUNC, DIR, ELEMS, SUFFIX)
static void fn() process(const SwsOpExec *exec, const void *priv, const int bx_start, const int y_start, int bx_end, int y_end)
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
DECL_SETUP(setup_filter_v, params, out)
int32_t * in_offset_x
Pixel offset map; for horizontal scaling, in bytes.
static const int weights[]
void * av_calloc(size_t nmemb, size_t size)
static void ff_op_priv_free(SwsOpPriv *priv)
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)
The exact code depends on how similar the blocks are and how related they are to the block
WRAP_COMMON_PATTERNS(min,.op=SWS_OP_MIN,.setup=ff_sws_setup_clamp,.flexible=true,)
static int setup_filter_h(const SwsImplParams *params, SwsImplResult *out)