Go to the documentation of this file.
38 #if HAVE_SPIRV_HEADERS_SPIRV_H || HAVE_SPIRV_UNIFIED1_SPIRV_H
44 #if ARCH_AARCH64 && HAVE_NEON
46 #elif ARCH_X86_64 && HAVE_X86ASM
50 #if HAVE_SPIRV_HEADERS_SPIRV_H || HAVE_SPIRV_UNIFIED1_SPIRV_H
103 for (
int i = 0;
i < 4;
i++) {
114 for (
int i = 0;
i < 4;
i++) {
115 const int src = swiz->
in[
i];
126 for (
int i = 0;
i < 4;
i++) {
136 switch (
op->rw.mode) {
170 for (
int i = 0;
i < 4;
i++)
178 for (
int i = 0;
i < 4;
i++)
186 for (
int i = 0;
i < 4;
i++) {
192 for (
int i = 0;
i < 4;
i++) {
201 for (
int i = 0;
i < 4;
i++) {
203 x[
i] =
op->clear.value[
i];
209 for (
int i = 0;
i < 4;
i++)
215 for (
int i = 0;
i < 4;
i++)
216 x[
i] = x[
i].den ?
Q((x[
i].num / x[
i].den) >>
op->shift.amount) : x[
i];
220 const AVRational64 orig[4] = { x[0], x[1], x[2], x[3] };
221 for (
int i = 0;
i < 4;
i++)
222 x[
i] = orig[
op->swizzle.in[
i]];
228 for (
int i = 0;
i < 4;
i++) {
229 x[
i] = x[
i].
den ?
Q(x[
i].num / x[
i].den) : x[
i];
230 if (
op->convert.expand)
237 for (
int i = 0;
i < 4;
i++) {
238 if (
op->dither.y_offset[
i] >= 0 && x[
i].
den)
243 for (
int i = 0;
i < 4;
i++)
247 for (
int i = 0;
i < 4;
i++)
252 const AVRational64 orig[4] = { x[0], x[1], x[2], x[3] };
253 for (
int i = 0;
i < 4;
i++) {
255 for (
int j = 0; j < 4; j++)
262 for (
int i = 0;
i < 4;
i++)
272 for (
int i = 0;
i < 3;
i++)
292 return ((
a &
b) & flags_and) | ((
a |
b) & flags_or);
300 for (
int i = 0;
i < 4;
i++) {
322 for (
int n = 0; n < ops->
num_ops; n++) {
335 memcpy(
op->comps.min, prev.
min,
sizeof(prev.
min));
336 memcpy(
op->comps.max, prev.
max,
sizeof(prev.
max));
342 for (
int i = 0;
i < 4;
i++) {
347 #define FORWARD(I, J, EXPR) do { \
348 SwsCompFlags flags = prev.flags[J]; \
349 op->comps.flags[I] = merge_comp_flags(op->comps.flags[I], (EXPR)); \
350 op->comps.dep_in[I] |= prev.dep_in[J]; \
353 #define RESET(I) do { \
354 op->comps.flags[I] = SWS_COMP_GARBAGE; \
355 op->comps.min[I] = op->comps.max[I] = (AVRational64) {0}; \
356 op->comps.dep_in[I] = SWS_COMP_NONE; \
363 for (
int i = 0;
i <
op->rw.elems;
i++) {
365 switch (
op->rw.mode) {
388 if (
op->rw.filter.op) {
394 for (
int i = 0;
i < 4;
i++) {
396 op->comps.min[
i] = prev.
min[
i];
397 op->comps.max[
i] = prev.
max[
i];
401 for (
int i = 0;
i <
op->rw.elems;
i++)
403 for (
int i = 0;
i < 4;
i++)
408 for (
int i = 0;
i < 4;
i++)
414 for (
int i = 0;
i < 4;
i++) {
416 if (
op->clamp.limit[
i].den)
424 for (
int i = 0;
i < 4;
i++) {
426 op->comps.min[
i] = prev.
min[
i];
427 op->comps.max[
i] = prev.
max[
i];
428 if (
op->dither.y_offset[
i] < 0)
437 for (
int i = 0;
i < 4;
i++) {
438 const int pattern =
op->pack.pattern[
i];
442 op->comps.min[
i] =
Q(0);
443 op->comps.max[
i] =
Q((1ULL << pattern) - 1);
449 for (
int i = 0;
i < 4;
i++) {
450 if (
op->pack.pattern[
i])
457 for (
int i = 0;
i < 4;
i++) {
460 if (
op->clear.value[
i].num == 0)
462 if (
op->clear.value[
i].den == 1)
470 for (
int i = 0;
i < 4;
i++)
474 for (
int i = 0;
i < 4;
i++) {
483 for (
int i = 0;
i < 4;
i++) {
486 for (
int j = 0; j < 4; j++) {
503 if (
op->lin.m[
i][4].num) {
505 if (
op->lin.m[
i][4].den != 1)
515 for (
int i = 0;
i < 4;
i++) {
517 if (
op->scale.factor.den != 1)
519 if (
op->scale.factor.num < 0)
529 for (
int i = 0;
i < 3;
i++) {
532 for (
int j = 0; j < 3; j++)
535 op->comps.min[
i] =
Q(0);
536 op->comps.max[
i] =
Q(UINT16_MAX);
540 op->comps.min[3] = prev.
min[3];
541 op->comps.max[3] = prev.
max[3];
554 for (
int n = ops->
num_ops - 1; n >= 0; n--) {
558 for (
int i = 0;
i < 4;
i++) {
559 op->comps.dep_out[
i] = need_out[
i];
567 for (
int i = 0;
i <
op->rw.elems;
i++)
569 for (
int i =
op->rw.elems;
i < 4;
i++)
570 need_in[
i] = need_out[
i];
582 for (
int i = 0;
i < 4;
i++)
583 need_in[
i] = need_out[
i];
586 for (
int i = 0;
i < 4 &&
op->pack.pattern[
i];
i++)
587 need_in[0] |= need_out[
i];
590 for (
int i = 0;
i < 4 &&
op->pack.pattern[
i];
i++)
591 need_in[
i] = need_out[0];
594 for (
int i = 0;
i < 4;
i++) {
596 need_in[
i] = need_out[
i];
600 for (
int i = 0;
i < 4;
i++)
601 need_in[
op->swizzle.in[
i]] |= need_out[
i];
604 for (
int i = 0;
i < 4;
i++) {
605 for (
int j = 0; j < 4; j++) {
606 if (
op->lin.m[
i][j].num)
607 need_in[j] |= need_out[
i];
612 for (
int i = 0;
i < 3;
i++)
613 need_in[
i] = need_out[0] | need_out[1] | need_out[2];
614 need_in[3] = need_out[3];
618 memcpy(need_out, need_in,
sizeof(need_in));
652 for (
int i = 0;
i < 4;
i++)
690 for (
int i = 0;
i <
copy->num_ops;
i++) {
694 if (
op->rw.filter.kernel)
733 const int end = ops->
num_ops - count;
735 for (
int i = 0;
i < count;
i++)
783 for (
int i = 0;
i < num_planes;
i++) {
805 for (
int i = 0;
i < 4;
i++) {
806 for (
int j = 0; j < 5; j++) {
835 for (
int i = 0;
i < 4;
i++) {
847 }
else if (q.
den == 1) {
849 }
else if (q.
num > 1000 || q.
num < -1000 || q.
den > 1000 || q.
den < -1000) {
859 for (
int i = 0;
i < 4;
i++) {
892 if (!
op->rw.filter.op)
908 op->pack.pattern[0],
op->pack.pattern[1],
909 op->pack.pattern[2],
op->pack.pattern[3]);
917 op->swizzle.x,
op->swizzle.y,
op->swizzle.z,
op->swizzle.w);
923 op->convert.expand ?
" (expand)" :
"");
927 1 <<
op->dither.size_log2, 1 <<
op->dither.size_log2,
928 op->dither.y_offset[0],
op->dither.y_offset[1],
929 op->dither.y_offset[2],
op->dither.y_offset[3]);
942 for (
int i = 0;
i < 4;
i++) {
944 for (
int j = 0; j < 5; j++) {
954 if (
op->scale.factor.den != 1)
966 av_bprintf(bp,
"%-20s: %s",
name,
op->lut3d.dynamic ?
"dynamic" :
"static");
976 for (
int i = 0;
i < nb_planes;
i++)
977 inorder &= order[
i] ==
i;
982 for (
int i = 0;
i < nb_planes;
i++)
1023 if (range_mask &
mask) {
1033 bool has_deps =
false;
1034 for (
int i = 0;
i < 4;
i++)
1035 has_deps |=
op->comps.dep_in[
i] ||
op->comps.dep_out[
i];
1048 av_log(
log,
lev,
" ('X' unused, 'z' byteswapped, '=' copied, '$' const, '+' integer, '0' zero)\n");
void ff_sws_op_list_free(SwsOpList **p_ops)
int ff_sws_rw_op_planes(const SwsOp *op)
Return the number of planes involved in a read/write operation.
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 minimum maximum flags name is the option name
SwsOpList * ff_sws_op_list_alloc(void)
static int av_bprint_is_complete(const AVBPrint *buf)
Test if the print buffer is complete (not truncated).
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
int filter_size
The number of source texels to convolve over for each row.
SwsOpList * ff_sws_op_list_duplicate(const SwsOpList *ops)
Returns a duplicate of ops, or NULL on OOM.
@ SWS_RW_PLANAR
Note: 1-component reads are either SWS_RW_PLANAR or SWS_RW_PACKED, depending on the underlying interp...
static void apply_filter_weights(SwsComps *comps, const SwsComps *prev, const SwsFilterWeights *weights)
static const char *const rw_mode_names[]
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
SwsComps comps_src
Source component metadata associated with pixel values from each corresponding component (in plane/me...
static SwsCompFlags merge_comp_flags(SwsCompFlags a, SwsCompFlags b)
const SwsOp * ff_sws_op_list_input(const SwsOpList *ops)
Returns the input operation for a given op list, or NULL if there is none (e.g.
int ff_sws_op_list_max_size(const SwsOpList *ops)
Returns the size of the largest pixel type used in ops.
const SwsOpBackend backend_x86
static void print_deps(AVBPrint *bp, const SwsCompMask *deps)
int ff_sws_op_list_append(SwsOpList *ops, SwsOp *op)
These will take over ownership of op and set it to {0}, even on failure.
static const struct @607 planes[]
SwsCompMask ff_sws_comp_mask_q4(const AVRational64 q[4])
static av_const bool ff_sws_pixel_type_is_int(SwsPixelType type)
Represents a computed filter kernel.
static char describe_comp_flags(SwsCompFlags flags)
void * av_dynarray2_add(void **tab_ptr, int *nb_ptr, size_t elem_size, const uint8_t *elem_data)
Add an element of size elem_size to a dynamic array.
static void desc_plane_order(AVBPrint *bp, int nb_planes, const uint8_t *order)
static AVRational64 av_min_q64(AVRational64 a, AVRational64 b)
#define FORWARD(I, J, EXPR)
SwsCompMask ff_sws_comp_mask_needed(const SwsOp *op)
void * av_memdup(const void *p, size_t size)
Duplicate a buffer with av_malloc().
void ff_sws_op_list_print(void *log, int lev, int lev_extra, const SwsOpList *ops)
Print out the contents of an operation list.
static void print_q4(AVBPrint *bp, const AVRational64 q4[4], SwsCompMask mask)
#define SWS_COMP_TEST(mask, X)
const SwsOpBackend *const ff_sws_op_backends[]
static void print_q(AVBPrint *bp, const AVRational64 q)
#define AV_BPRINT_SIZE_AUTOMATIC
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
static int16_t mult(Float11 *f1, Float11 *f2)
trying all byte sequences megabyte in length and selecting the best looking sequence will yield cases to try But first
const SwsOpBackend backend_aarch64
#define SWS_OP_NEEDED(op, idx)
#define flags(name, subs,...)
static AVRational64 ff_sws_pixel_expand(SwsPixelType from, SwsPixelType to)
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.
const SwsOpBackend backend_c
Copyright (C) 2025 Niklas Haas.
#define av_assert0(cond)
assert() equivalent, that is always enabled.
int av_cmp_q64(AVRational64 a, AVRational64 b)
Compare two 64-bit rationals.
uint8_t SwsCompMask
Bit-mask of components.
const SwsOp * ff_sws_op_list_output(const SwsOpList *ops)
Returns the output operation for a given op list, or NULL if there is none.
AVRational64 av_mul_q64(AVRational64 b, AVRational64 c)
Multiply two 64-bit rationals.
static av_const int ff_sws_pixel_type_size(SwsPixelType type)
bool ff_sws_op_list_is_noop(const SwsOpList *ops)
Returns whether an op list represents a true no-op operation, i.e.
#define av_unreachable(msg)
Asserts that are used as compiler optimization hints depending upon ASSERT_LEVEL and NBDEBUG.
SwsOpType
Copyright (C) 2025 Niklas Haas.
void ff_sws_op_list_remove_at(SwsOpList *ops, int index, int count)
void ff_sws_apply_op_q(const SwsOp *op, AVRational64 x[4])
Apply an operation to an AVRational64.
int src_size
Copy of the parameters used to generate this filter, for reference.
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
void ff_sws_comp_mask_swizzle(SwsCompMask *mask, const SwsSwizzleOp *swiz)
static void copy(const float *p1, float *p2, const int length)
static int shift(int a, int b)
#define i(width, name, range_min, range_max)
int ff_sws_op_list_insert_at(SwsOpList *ops, int index, SwsOp *op)
uint32_t ff_sws_linear_mask(const SwsLinearOp *c)
void ff_sws_op_list_update_comps(SwsOpList *ops)
Infer + propagate known information about components.
64-bit Rational number (pair of numerator and denominator).
void * av_refstruct_ref(void *obj)
Create a new reference to an object managed via this API, i.e.
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
static void op_uninit(SwsOp *op)
char name[16]
Extra metadata about the filter, used to inform the optimizer / range tracker about the filter's beha...
void ff_sws_op_desc(AVBPrint *bp, const SwsOp *op)
Describe an operation in human-readable form.
void av_refstruct_unref(void *objp)
Decrement the reference count of the underlying object and automatically free the object if there are...
#define av_assert2(cond)
assert() equivalent, that does lie in speed critical code.
static const int weights[]
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
static LevelCodes lev[4+3+3]
static double bound(const double threshold, const double val)
const SwsOpBackend backend_murder
#define FFSWAP(type, a, b)
void av_bprintf(AVBPrint *buf, const char *fmt,...)
static double av_q2d_64(AVRational64 a)
Convert an AVRational64 to a double.
static AVRational64 av_make_q64(int64_t num, int64_t den)
Create an AVRational64.
const void * av_refstruct_ref_c(const void *obj)
Analog of av_refstruct_ref(), but for constant objects.
const char * ff_sws_pixel_type_name(SwsPixelType type)
static AVRational64 av_max_q64(AVRational64 a, AVRational64 b)
void av_bprint_clear(AVBPrint *buf)
Reset the string to "" but keep internal allocated data.
@ SWS_FILTER_SCALE
14-bit coefficients are picked to fit comfortably within int16_t for efficient SIMD processing (e....
static void scale(int *out, const int *in, const int w, const int h, const int shift)
static void ff_sws_pack_op_decode(const SwsOp *op, uint64_t mask[4], int shift[4])
struct SwsReadWriteOp::@583 filter
Filter kernel to apply to each plane while sampling.
SwsReadWriteMode mode
Examples: rgba = 4x u8 packed yuv444p = 3x u8 rgb565 = 1x u16 <- use SWS_OP_UNPACK to unpack monow = ...
Helper struct for representing a list of operations.
const char * ff_sws_op_type_name(SwsOpType op)
static uint32_t BS_FUNC() read(BSCTX *bc, unsigned int n)
Return n bits from the buffer, n has to be in the 0-32 range.
#define ff_sws_comp_mask_str(mask)
AVRational64 av_add_q64(AVRational64 b, AVRational64 c)
Add two 64-bit rationals.