Commit 02dbbf671f for ffmpeg

commit 02dbbf671f5694c6635e7f2f3b38ffbe4f4fef51
Author: Niklas Haas <git@haasn.dev>
Date:   Sat Nov 7 15:30:51 2026 +0100

    swscale/ops_chain: make SwsOpImpl.priv generic

    SwsOpPriv is now only used by the generic C code to access op data set up
    by the generic pack helpers, so move it there.

    Signed-off-by: Niklas Haas <git@haasn.dev>

diff --git a/libswscale/aarch64/ops.c b/libswscale/aarch64/ops.c
index 10eb3e58d6..8ded09ffc6 100644
--- a/libswscale/aarch64/ops.c
+++ b/libswscale/aarch64/ops.c
@@ -39,7 +39,6 @@ static_assert(offsetof_exec_in_bump  == offsetof(SwsOpExec, in_bump),  "SwsOpExe
 static_assert(offsetof_exec_out_bump == offsetof(SwsOpExec, out_bump), "SwsOpExec layout mismatch");
 static_assert(offsetof_impl_func     == offsetof(SwsOpImpl, func),     "SwsOpImpl layout mismatch");
 static_assert(offsetof_impl_priv     == offsetof(SwsOpImpl, priv),     "SwsOpImpl layout mismatch");
-static_assert(sizeof_impl            == sizeof(SwsOpImpl),             "SwsOpImpl layout mismatch");
 static_assert(alignof_impl           == alignof(SwsOpImpl),            "SwsOpImpl layout mismatch");

 /*********************************************************************/
diff --git a/libswscale/aarch64/ops_impl.h b/libswscale/aarch64/ops_impl.h
index d6a4f46135..7b05962a4a 100644
--- a/libswscale/aarch64/ops_impl.h
+++ b/libswscale/aarch64/ops_impl.h
@@ -117,7 +117,6 @@ static inline int aarch64_priv_size(const SwsAArch64OpImplParams *params)
 #define offsetof_exec_out_bump 160
 #define offsetof_impl_func       0
 #define offsetof_impl_priv       8
-#define sizeof_impl             24
 #define alignof_impl             8

 #endif /* SWSCALE_AARCH64_OPS_IMPL_H */
diff --git a/libswscale/ops_chain.h b/libswscale/ops_chain.h
index 55df6ca4e2..de18a20c45 100644
--- a/libswscale/ops_chain.h
+++ b/libswscale/ops_chain.h
@@ -42,29 +42,6 @@

 typedef struct SwsUOpTable SwsUOpTable;

-/**
- * Private data for each kernel.
- */
-typedef union SwsOpPriv {
-    char data[16];
-
-    /* Common types */
-    void *ptr;
-    uint8_t    u8[16];
-    int8_t     i8[16];
-    uint16_t   u16[8];
-    int16_t    i16[8];
-    uint32_t   u32[4];
-    int32_t    i32[4];
-    float      f32[4];
-    uint64_t   u64[2];
-    int64_t    i64[2];
-    uintptr_t uptr[2];
-    intptr_t  iptr[2];
-} SwsOpPriv;
-
-static_assert(sizeof(SwsOpPriv) == 16, "SwsOpPriv size mismatch");
-
 /**
  * Per-kernel execution context.
  *
@@ -72,12 +49,11 @@ static_assert(sizeof(SwsOpPriv) == 16, "SwsOpPriv size mismatch");
  */
 typedef void (*SwsFuncPtr)(void);
 typedef struct SwsOpImpl {
-    SwsFuncPtr func; /* Function pointer for this operation. */
-    SwsOpPriv  priv; /* Private data for this operation. */
+    SwsFuncPtr func;   /* Function pointer for this operation. */
+    char       priv[]; /* Private data for this operation. */
 } SwsOpImpl;

 #if ARCH_X86_64 || ARCH_AARCH64
-static_assert(sizeof(SwsOpImpl) == 24,        "SwsOpImpl layout mismatch");
 static_assert(offsetof(SwsOpImpl, priv) == 8, "SwsOpImpl layout mismatch");
 static_assert(alignof(SwsOpImpl) == sizeof(void *), "SwsOpImpl alignment mismatch");
 #endif
diff --git a/libswscale/uops_tmpl.c b/libswscale/uops_tmpl.c
index 84e2022e62..5473df8082 100644
--- a/libswscale/uops_tmpl.c
+++ b/libswscale/uops_tmpl.c
@@ -275,7 +275,7 @@ DECL_READ(read_planar_fv, const SwsCompMask mask, const SwsPixelType type)
 {
     av_assert2(type == SWS_PIXEL_F32);
     const SwsOpExec *exec = iter->exec;
-    const SwsFilterPriv *priv = (const SwsFilterPriv *) impl->priv.data;
+    const SwsFilterPriv *priv = SWS_OP_PRIV(impl);
     const float *restrict weights = priv->weights;
     const int filter_size = priv->filter_size;
     weights += filter_size * iter->y;
@@ -335,7 +335,7 @@ DECL_READ(read_planar_fh, const SwsCompMask mask, const SwsPixelType type)
 {
     av_assert2(type == SWS_PIXEL_F32);
     const SwsOpExec *exec = iter->exec;
-    const SwsFilterPriv *priv = (const SwsFilterPriv *) impl->priv.data;
+    const SwsFilterPriv *priv = SWS_OP_PRIV(impl);
     const int *restrict weights = priv->weights;
     const int filter_size = priv->filter_size;
     const float scale = 1.0f / SWS_FILTER_SCALE;
@@ -637,10 +637,11 @@ DECL_FUNC(clear, const SwsCompMask mask, const SwsCompMask one,
 {
     #define ONE(N)  SWS_COMP_TEST(one, N)
     #define ZERO(N) SWS_COMP_TEST(zero, N)
-    const pixel_t cx = ONE(0) ? PIXEL_MAX : ZERO(0) ? 0 : impl->priv.px[0];
-    const pixel_t cy = ONE(1) ? PIXEL_MAX : ZERO(1) ? 0 : impl->priv.px[1];
-    const pixel_t cz = ONE(2) ? PIXEL_MAX : ZERO(2) ? 0 : impl->priv.px[2];
-    const pixel_t cw = ONE(3) ? PIXEL_MAX : ZERO(3) ? 0 : impl->priv.px[3];
+    const SwsOpPriv *priv = SWS_OP_PRIV(impl);
+    const pixel_t cx = ONE(0) ? PIXEL_MAX : ZERO(0) ? 0 : priv->px[0];
+    const pixel_t cy = ONE(1) ? PIXEL_MAX : ZERO(1) ? 0 : priv->px[1];
+    const pixel_t cz = ONE(2) ? PIXEL_MAX : ZERO(2) ? 0 : priv->px[2];
+    const pixel_t cw = ONE(3) ? PIXEL_MAX : ZERO(3) ? 0 : priv->px[3];

     SWS_LOOP
     for (int i = 0; i < SWS_BLOCK_SIZE; i++) {
@@ -663,7 +664,8 @@ SWS_FOR_STRUCT(PX, CLEAR, DECL_ENTRY, .setup = ff_sws_setup_vec4)

 DECL_FUNC(scale, const SwsCompMask mask)
 {
-    const pixel_t scale = impl->priv.px[0];
+    const SwsOpPriv *priv = SWS_OP_PRIV(impl);
+    const pixel_t scale = priv->px[0];

     SWS_LOOP
     for (int i = 0; i < SWS_BLOCK_SIZE; i++) {
@@ -678,12 +680,14 @@ DECL_FUNC(scale, const SwsCompMask mask)

 DECL_FUNC(add, const SwsCompMask mask)
 {
+    const SwsOpPriv *priv = SWS_OP_PRIV(impl);
+
     SWS_LOOP
     for (int i = 0; i < SWS_BLOCK_SIZE; i++) {
-        if (X) x[i] += impl->priv.px[0];
-        if (Y) y[i] += impl->priv.px[1];
-        if (Z) z[i] += impl->priv.px[2];
-        if (W) w[i] += impl->priv.px[3];
+        if (X) x[i] += priv->px[0];
+        if (Y) y[i] += priv->px[1];
+        if (Z) z[i] += priv->px[2];
+        if (W) w[i] += priv->px[3];
     }

     CONTINUE(sizeof(pixel_t[4]), x, y, z, w);
@@ -691,12 +695,14 @@ DECL_FUNC(add, const SwsCompMask mask)

 DECL_FUNC(min, const SwsCompMask mask)
 {
+    const SwsOpPriv *priv = SWS_OP_PRIV(impl);
+
     SWS_LOOP
     for (int i = 0; i < SWS_BLOCK_SIZE; i++) {
-        if (X) x[i] = FFMIN(x[i], impl->priv.px[0]);
-        if (Y) y[i] = FFMIN(y[i], impl->priv.px[1]);
-        if (Z) z[i] = FFMIN(z[i], impl->priv.px[2]);
-        if (W) w[i] = FFMIN(w[i], impl->priv.px[3]);
+        if (X) x[i] = FFMIN(x[i], priv->px[0]);
+        if (Y) y[i] = FFMIN(y[i], priv->px[1]);
+        if (Z) z[i] = FFMIN(z[i], priv->px[2]);
+        if (W) w[i] = FFMIN(w[i], priv->px[3]);
     }

     CONTINUE(sizeof(pixel_t[4]), x, y, z, w);
@@ -704,12 +710,14 @@ DECL_FUNC(min, const SwsCompMask mask)

 DECL_FUNC(max, const SwsCompMask mask)
 {
+    const SwsOpPriv *priv = SWS_OP_PRIV(impl);
+
     SWS_LOOP
     for (int i = 0; i < SWS_BLOCK_SIZE; i++) {
-        if (X) x[i] = FFMAX(x[i], impl->priv.px[0]);
-        if (Y) y[i] = FFMAX(y[i], impl->priv.px[1]);
-        if (Z) z[i] = FFMAX(z[i], impl->priv.px[2]);
-        if (W) w[i] = FFMAX(w[i], impl->priv.px[3]);
+        if (X) x[i] = FFMAX(x[i], priv->px[0]);
+        if (Y) y[i] = FFMAX(y[i], priv->px[1]);
+        if (Z) z[i] = FFMAX(z[i], priv->px[2]);
+        if (W) w[i] = FFMAX(w[i], priv->px[3]);
     }

     CONTINUE(sizeof(pixel_t[4]), x, y, z, w);
@@ -768,7 +776,8 @@ DECL_FUNC(dither, const SwsCompMask mask,
     const int size   = 1 << size_log2;
     const int stride = FFMAX(size, SWS_BLOCK_SIZE);

-    const pixel_t *matrix = impl->priv.ptr;
+    const SwsOpPriv *priv = SWS_OP_PRIV(impl);
+    const pixel_t *matrix = priv->ptr;
     matrix += (iter->y & (size - 1)) * stride;
     matrix += (iter->x & (size - 1)) & ~(SWS_BLOCK_SIZE - 1);

@@ -828,7 +837,8 @@ DECL_SETUP(setup_linear, params, out)
  */
 DECL_FUNC(linear, const SwsCompMask mask, const uint32_t one, const uint32_t zero)
 {
-    const fn(LinCoeffs) c = *(const fn(LinCoeffs) *) impl->priv.ptr;
+    const SwsOpPriv *priv = SWS_OP_PRIV(impl);
+    const fn(LinCoeffs) c = *(const fn(LinCoeffs) *) priv->ptr;

     SWS_LOOP
     for (int i = 0; i < SWS_BLOCK_SIZE; i++) {
@@ -1006,7 +1016,8 @@ vec3_t fn(lut3d_dynamic)(const SwsLut3D *restrict lut3d, vec3_t rgb)

 DECL_FUNC(lut3d, const SwsCompMask mask, const int dynamic)
 {
-    const SwsLut3D *restrict lut3d = impl->priv.ptr;
+    const SwsOpPriv *priv = SWS_OP_PRIV(impl);
+    const SwsLut3D *restrict lut3d = priv->ptr;

     SWS_LOOP
     for (int i = 0; i < SWS_BLOCK_SIZE; i++) {
diff --git a/libswscale/uops_tmpl.h b/libswscale/uops_tmpl.h
index 388ed4c311..2103028e49 100644
--- a/libswscale/uops_tmpl.h
+++ b/libswscale/uops_tmpl.h
@@ -63,6 +63,17 @@ typedef struct SwsOpIter {
     const SwsOpExec *exec;
 } SwsOpIter;

+/* Private data for generic kernels. */
+typedef union SwsOpPriv {
+    float    f32[4];
+    uint32_t u32[4];
+    uint16_t u16[4];
+    uint8_t  u8[4];
+    void    *ptr;
+} SwsOpPriv;
+
+#define SWS_OP_PRIV(impl) ((const void *) (impl)->priv)
+
 /* Private data for filtered reads */
 typedef struct SwsFilterPriv {
     void *weights;
@@ -118,7 +129,7 @@ static_assert(alignof(SwsFilterPriv) <= alignof(SwsOpPriv),
 #define CALL(NAME, ...) fn(NAME)(iter, impl, x, y, z, w, __VA_ARGS__)

 #define NEXT_IMPL(N)                                                            \
-    ((const SwsOpImpl *) &impl->priv.data[FFALIGN(N, alignof(SwsOpImpl))])
+    ((const SwsOpImpl *) &impl->priv[FFALIGN(N, alignof(SwsOpImpl))])

 /* Helper macro to call into the next continuation with a given type; N gives
  * the size of private data consumed by this op */