PR #22771 opened by Kacper Michajłow (kasper93) URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/22771 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/22771.patch
The glue code doesn't care about types, so long the functions are chained correctly. Let's not pretend there is any type safety there, as the function pointers were casted anyway from unrelated types. Particularly some f32 and u32 are shared. This fixes errors like so: src/libswscale/ops_tmpl_int.c:471:1: runtime error: call to function linear_diagoff3_f32 through pointer to incorrect function type 'void (*)(struct SwsOpIter *, const struct SwsOpImpl *, unsigned int *, unsigned int *, unsigned int *, unsigned int *)' libswscale/ops_tmpl_float.c:208: note: linear_diagoff3_f32 defined here Fixes: #22332 From bcc97faa60c065153bde7cf5b0aee29fa847c2b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20Michaj=C5=82ow?= <[email protected]> Date: Thu, 9 Apr 2026 19:40:48 +0200 Subject: [PATCH] swscale/ops: remove type from continuation functions The glue code doesn't care about types, so long the functions are chained correctly. Let's not pretend there is any type safety there, as the function pointers were casted anyway from unrelated types. Particularly some f32 and u32 are shared. This fixes errors like so: src/libswscale/ops_tmpl_int.c:471:1: runtime error: call to function linear_diagoff3_f32 through pointer to incorrect function type 'void (*)(struct SwsOpIter *, const struct SwsOpImpl *, unsigned int *, unsigned int *, unsigned int *, unsigned int *)' libswscale/ops_tmpl_float.c:208: note: linear_diagoff3_f32 defined here Fixes: #22332 --- libswscale/ops_backend.h | 18 ++++----- libswscale/ops_chain.c | 2 +- libswscale/ops_chain.h | 10 +++-- libswscale/ops_tmpl_common.c | 16 ++++---- libswscale/ops_tmpl_float.c | 4 +- libswscale/ops_tmpl_int.c | 71 ++++++++++++++++++++---------------- 6 files changed, 66 insertions(+), 55 deletions(-) diff --git a/libswscale/ops_backend.h b/libswscale/ops_backend.h index f0b89d51c0..3ec547997e 100644 --- a/libswscale/ops_backend.h +++ b/libswscale/ops_backend.h @@ -43,14 +43,14 @@ * Internal context holding per-iter execution data. The data pointers will be * directly incremented by the corresponding read/write functions. */ -typedef struct SwsOpIter { +struct SwsOpIter { uintptr_t in[4]; uintptr_t out[4]; int x, y; /* Link back to per-slice execution context */ const SwsOpExec *exec; -} SwsOpIter; +}; #ifdef __clang__ # define SWS_FUNC @@ -93,7 +93,7 @@ typedef struct SwsOpIter { /* Helper macros to call into functions declared with DECL_FUNC_* */ #define CALL(FUNC, ...) \ - fn(FUNC)(iter, impl, x, y, z, w, __VA_ARGS__) + fn(FUNC)(iter, impl, (pixel_t *) x, (pixel_t *) y, (pixel_t *) z, (pixel_t *) w, __VA_ARGS__) #define CALL_READ(FUNC, ...) \ CALL(FUNC, (const pixel_t *) iter->in[0], (const pixel_t *) iter->in[1], \ @@ -108,14 +108,12 @@ typedef struct SwsOpIter { #define DECL_IMPL(NAME) \ static SWS_FUNC void fn(NAME)(SwsOpIter *restrict iter, \ const SwsOpImpl *restrict impl, \ - block_t x, block_t y, \ - block_t z, block_t w) + void *x, void *y, \ + void *z, void *w) -/* Helper macro to call into the next continuation with a given type */ -#define CONTINUE(TYPE, ...) \ - ((void (*)(SwsOpIter *, const SwsOpImpl *, \ - TYPE x, TYPE y, TYPE z, TYPE w)) impl->cont) \ - (iter, &impl[1], __VA_ARGS__) +/* Helper macro to call into the next continuation */ +#define CONTINUE(X, Y, Z, W) \ + impl->cont(iter, &impl[1], (X), (Y), (Z), (W)) /* Helper macros for common op setup code */ #define DECL_SETUP(NAME, PARAMS, OUT) \ diff --git a/libswscale/ops_chain.c b/libswscale/ops_chain.c index 1730fdfe61..d6beeb4253 100644 --- a/libswscale/ops_chain.c +++ b/libswscale/ops_chain.c @@ -53,7 +53,7 @@ int ff_sws_op_chain_append(SwsOpChain *chain, SwsFuncPtr func, return AVERROR(EINVAL); av_assert1(func); - chain->impl[idx].cont = func; + chain->impl[idx].cont = (SwsContFunc) func; chain->impl[idx + 1].priv = *priv; chain->free[idx + 1] = free; chain->num_impl++; diff --git a/libswscale/ops_chain.h b/libswscale/ops_chain.h index fc0cd930f8..167fd30b97 100644 --- a/libswscale/ops_chain.h +++ b/libswscale/ops_chain.h @@ -68,10 +68,14 @@ static_assert(sizeof(SwsOpPriv) == 16, "SwsOpPriv size mismatch"); * Note: This struct is hard-coded in assembly, so do not change the layout. */ typedef void (*SwsFuncPtr)(void); -typedef struct SwsOpImpl { - SwsFuncPtr cont; /* [offset = 0] Continuation for this operation. */ +typedef struct SwsOpIter SwsOpIter; +typedef struct SwsOpImpl SwsOpImpl; +typedef void (*SwsContFunc)(SwsOpIter *, const SwsOpImpl *, + void *, void *, void *, void *); +struct SwsOpImpl { + SwsContFunc cont; /* [offset = 0] Continuation for this operation. */ SwsOpPriv priv; /* [offset = 16] Private data for this operation. */ -} SwsOpImpl; +}; static_assert(sizeof(SwsOpImpl) == 32, "SwsOpImpl layout mismatch"); static_assert(offsetof(SwsOpImpl, priv) == 16, "SwsOpImpl layout mismatch"); diff --git a/libswscale/ops_tmpl_common.c b/libswscale/ops_tmpl_common.c index 3817a437e5..dbdb91dc5b 100644 --- a/libswscale/ops_tmpl_common.c +++ b/libswscale/ops_tmpl_common.c @@ -41,7 +41,7 @@ DECL_PATTERN(convert_uint##N) wu[i] = w[i]; \ } \ \ - CONTINUE(u##N##block_t, xu, yu, zu, wu); \ + CONTINUE(xu, yu, zu, wu); \ } \ \ WRAP_COMMON_PATTERNS(convert_uint##N, \ @@ -75,7 +75,7 @@ DECL_PATTERN(clear) w[i] = impl->priv.px[3]; } - CONTINUE(block_t, x, y, z, w); + CONTINUE(x, y, z, w); } #define WRAP_CLEAR(X, Y, Z, W) \ @@ -119,7 +119,7 @@ DECL_PATTERN(min) w[i] = FFMIN(w[i], impl->priv.px[3]); } - CONTINUE(block_t, x, y, z, w); + CONTINUE(x, y, z, w); } DECL_PATTERN(max) @@ -136,7 +136,7 @@ DECL_PATTERN(max) w[i] = FFMAX(w[i], impl->priv.px[3]); } - CONTINUE(block_t, x, y, z, w); + CONTINUE(x, y, z, w); } WRAP_COMMON_PATTERNS(min, @@ -167,7 +167,7 @@ DECL_PATTERN(scale) w[i] *= scale; } - CONTINUE(block_t, x, y, z, w); + CONTINUE(x, y, z, w); } WRAP_COMMON_PATTERNS(scale, @@ -239,7 +239,7 @@ DECL_READ(filter_v, const int elems) for (int i = 0; i < elems; i++) iter->in[i] += sizeof(block_t); - CONTINUE(f32block_t, xs, ys, zs, ws); + CONTINUE(xs, ys, zs, ws); } DECL_SETUP(setup_filter_h, params, out) @@ -292,7 +292,7 @@ DECL_READ(filter_h, const int elems) weights += filter_size; } - CONTINUE(f32block_t, xs, ys, zs, ws); + CONTINUE(xs, ys, zs, ws); } #define WRAP_FILTER(FUNC, DIR, ELEMS, SUFFIX) \ @@ -337,7 +337,7 @@ static void fn(process)(const SwsOpExec *exec, const void *priv, for (iter->y = y_start; iter->y < y_end; iter->y++) { for (int block = bx_start; block < bx_end; block++) { iter->x = block * SWS_BLOCK_SIZE; - CONTINUE(block_t, (void *) x, (void *) y, (void *) z, (void *) w); + CONTINUE(x, y, z, w); } const int y_bump = exec->in_bump_y ? exec->in_bump_y[iter->y] : 0; diff --git a/libswscale/ops_tmpl_float.c b/libswscale/ops_tmpl_float.c index 0d00714ff4..6efe4aa1cf 100644 --- a/libswscale/ops_tmpl_float.c +++ b/libswscale/ops_tmpl_float.c @@ -98,7 +98,7 @@ DECL_FUNC(dither, const int size_log2) DITHER_COMP(z, 2) DITHER_COMP(w, 3) - CONTINUE(block_t, x, y, z, w); + CONTINUE(x, y, z, w); } #define WRAP_DITHER(N) \ @@ -185,7 +185,7 @@ DECL_FUNC(linear_mask, const uint32_t mask) w[i] += (mask & SWS_MASK(3, 3)) ? c.m[3][3] * ww : ww; } - CONTINUE(block_t, x, y, z, w); + CONTINUE(x, y, z, w); } #define WRAP_LINEAR(NAME, MASK) \ diff --git a/libswscale/ops_tmpl_int.c b/libswscale/ops_tmpl_int.c index b010513bc5..76b001e95e 100644 --- a/libswscale/ops_tmpl_int.c +++ b/libswscale/ops_tmpl_int.c @@ -71,7 +71,7 @@ DECL_READ(read_planar, const int elems) w[i] = in3[i]; } - CONTINUE(block_t, x, y, z, w); + CONTINUE(x, y, z, w); } DECL_READ(read_packed, const int elems) @@ -87,7 +87,7 @@ DECL_READ(read_packed, const int elems) w[i] = in0[elems * i + 3]; } - CONTINUE(block_t, x, y, z, w); + CONTINUE(x, y, z, w); } DECL_WRITE(write_planar, const int elems) @@ -178,7 +178,7 @@ DECL_READ(read_nibbles, const int elems) x[i + 1] = val & 0xF; /* low nibble */ } - CONTINUE(block_t, x, y, z, w); + CONTINUE(x, y, z, w); } DECL_READ(read_bits, const int elems) @@ -196,7 +196,7 @@ DECL_READ(read_bits, const int elems) x[i + 7] = (val >> 0) & 1; } - CONTINUE(block_t, x, y, z, w); + CONTINUE(x, y, z, w); } WRAP_READ(read_nibbles, 1, 1, false) @@ -243,7 +243,7 @@ DECL_PATTERN(swap_bytes) w[i] = SWAP_BYTES(w[i]); } - CONTINUE(block_t, x, y, z, w); + CONTINUE(x, y, z, w); } WRAP_COMMON_PATTERNS(swap_bytes, .op = SWS_OP_SWAP_BYTES); @@ -266,7 +266,7 @@ DECL_PATTERN(expand16) w16[i] = w[i] << 8 | w[i]; } - CONTINUE(u16block_t, x16, y16, z16, w16); + CONTINUE(x16, y16, z16, w16); } WRAP_COMMON_PATTERNS(expand16, @@ -287,7 +287,7 @@ DECL_PATTERN(expand32) w32[i] = (uint32_t)w[i] << 24 | w[i] << 16 | w[i] << 8 | w[i]; } - CONTINUE(u32block_t, x32, y32, z32, w32); + CONTINUE(x32, y32, z32, w32); } WRAP_COMMON_PATTERNS(expand32, @@ -300,18 +300,20 @@ WRAP_COMMON_PATTERNS(expand32, #define WRAP_PACK_UNPACK(X, Y, Z, W) \ inline DECL_IMPL(pack_##X##Y##Z##W) \ { \ + pixel_t *restrict px = (pixel_t *) x, *restrict py = (pixel_t *) y, \ + *restrict pz = (pixel_t *) z, *restrict pw = (pixel_t *) w; \ SWS_LOOP \ for (int i = 0; i < SWS_BLOCK_SIZE; i++) { \ - x[i] = x[i] << (Y+Z+W); \ + px[i] = px[i] << (Y+Z+W); \ if (Y) \ - x[i] |= y[i] << (Z+W); \ + px[i] |= py[i] << (Z+W); \ if (Z) \ - x[i] |= z[i] << W; \ + px[i] |= pz[i] << W; \ if (W) \ - x[i] |= w[i]; \ + px[i] |= pw[i]; \ } \ \ - CONTINUE(block_t, x, y, z, w); \ + CONTINUE(x, y, z, w); \ } \ \ DECL_ENTRY(pack_##X##Y##Z##W, \ @@ -321,19 +323,21 @@ DECL_ENTRY(pack_##X##Y##Z##W, \ inline DECL_IMPL(unpack_##X##Y##Z##W) \ { \ + pixel_t *restrict px = (pixel_t *) x, *restrict py = (pixel_t *) y, \ + *restrict pz = (pixel_t *) z, *restrict pw = (pixel_t *) w; \ SWS_LOOP \ for (int i = 0; i < SWS_BLOCK_SIZE; i++) { \ - const pixel_t val = x[i]; \ - x[i] = val >> (Y+Z+W); \ + const pixel_t val = px[i]; \ + px[i] = val >> (Y+Z+W); \ if (Y) \ - y[i] = (val >> (Z+W)) & ((1 << Y) - 1); \ + py[i] = (val >> (Z+W)) & ((1 << Y) - 1); \ if (Z) \ - z[i] = (val >> W) & ((1 << Z) - 1); \ + pz[i] = (val >> W) & ((1 << Z) - 1); \ if (W) \ - w[i] = val & ((1 << W) - 1); \ + pw[i] = val & ((1 << W) - 1); \ } \ \ - CONTINUE(block_t, x, y, z, w); \ + CONTINUE(x, y, z, w); \ } \ \ DECL_ENTRY(unpack_##X##Y##Z##W, \ @@ -363,7 +367,7 @@ DECL_PATTERN(lshift) w[i] <<= amount; } - CONTINUE(block_t, x, y, z, w); + CONTINUE(x, y, z, w); } DECL_PATTERN(rshift) @@ -378,7 +382,7 @@ DECL_PATTERN(rshift) w[i] >>= amount; } - CONTINUE(block_t, x, y, z, w); + CONTINUE(x, y, z, w); } WRAP_COMMON_PATTERNS(lshift, @@ -406,7 +410,7 @@ DECL_PATTERN(convert_float) wf[i] = w[i]; } - CONTINUE(f32block_t, xf, yf, zf, wf); + CONTINUE(xf, yf, zf, wf); } WRAP_COMMON_PATTERNS(convert_float, @@ -422,9 +426,10 @@ WRAP_COMMON_PATTERNS(convert_float, static SWS_FUNC void \ fn(swizzle_##X##Y##Z##W)(SwsOpIter *restrict iter, \ const SwsOpImpl *restrict impl, \ - block_t c0, block_t c1, block_t c2, block_t c3) \ + void *c0, void *c1, \ + void *c2, void *c3) \ { \ - CONTINUE(block_t, c##X, c##Y, c##Z, c##W); \ + CONTINUE(c##X, c##Y, c##Z, c##W); \ } \ \ DECL_ENTRY(swizzle_##X##Y##Z##W, \ @@ -452,17 +457,21 @@ DECL_SWIZZLE(3, 1, 2, 0) DECL_SWIZZLE(0, 3, 2, 1) /* Broadcast luma -> rgb (only used for y(a) -> rgb(a)) */ -#define DECL_EXPAND_LUMA(X, W, T0, T1) \ +#define DECL_EXPAND_LUMA(X, W, D0, D1) \ static SWS_FUNC void \ fn(expand_luma_##X##W)(SwsOpIter *restrict iter, \ const SwsOpImpl *restrict impl, \ - block_t c0, block_t c1, block_t c2, block_t c3) \ + void *c0, void *c1, \ + void *c2, void *c3) \ { \ + pixel_t *src = (pixel_t *) c0; \ + pixel_t *dst0 = (pixel_t *) c##D0; \ + pixel_t *dst1 = (pixel_t *) c##D1; \ SWS_LOOP \ for (int i = 0; i < SWS_BLOCK_SIZE; i++) \ - T0[i] = T1[i] = c0[i]; \ + dst0[i] = dst1[i] = src[i]; \ \ - CONTINUE(block_t, c##X, T0, T1, c##W); \ + CONTINUE(c##X, c##D0, c##D1, c##W); \ } \ \ DECL_ENTRY(expand_luma_##X##W, \ @@ -470,10 +479,10 @@ DECL_ENTRY(expand_luma_##X##W, .swizzle.in = { X, 0, 0, W }, \ ); -DECL_EXPAND_LUMA(0, 3, c1, c2) -DECL_EXPAND_LUMA(3, 0, c1, c2) -DECL_EXPAND_LUMA(1, 0, c2, c3) -DECL_EXPAND_LUMA(0, 1, c2, c3) +DECL_EXPAND_LUMA(0, 3, 1, 2) +DECL_EXPAND_LUMA(3, 0, 1, 2) +DECL_EXPAND_LUMA(1, 0, 2, 3) +DECL_EXPAND_LUMA(0, 1, 2, 3) static const SwsOpTable fn(op_table_int) = { .block_size = SWS_BLOCK_SIZE, -- 2.52.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
