Commit 80e3425ba2 for ffmpeg
commit 80e3425ba2141f1c38d64bbc9a78a649a2653db6
Author: Niklas Haas <git@haasn.dev>
Date: Sat Nov 7 14:19:03 2026 +0100
swscale/ops_chain: use abstract packed data buffer
Instead of forcing a single layout (SwsOpPriv), this will allow each
op to define its own data layout; freeing us from the 16-byte constraint
for op private data.
Currently, we still hard-code the assumption that the data layout exactly
matches SwsOpPriv, but this will change in the following commits.
Signed-off-by: Niklas Haas <git@haasn.dev>
diff --git a/libswscale/aarch64/ops.c b/libswscale/aarch64/ops.c
index 5755bac610..4ee93329a7 100644
--- a/libswscale/aarch64/ops.c
+++ b/libswscale/aarch64/ops.c
@@ -184,7 +184,7 @@ static int compile_uops_aarch64(SwsContext *ctx, const SwsUOpList *uops,
ret = aarch64_setup(&uops->ops[i], ¶ms, &res);
if (ret < 0)
goto error;
- ret = ff_sws_op_chain_append(chain, func, res.ref, &res.priv);
+ ret = ff_sws_op_chain_append(chain, func, res.ref, &res.priv, sizeof(res.priv));
av_refstruct_unref(&res.ref);
if (ret < 0)
goto error;
diff --git a/libswscale/ops_chain.c b/libswscale/ops_chain.c
index 0e2bd237a8..5b0367d6b5 100644
--- a/libswscale/ops_chain.c
+++ b/libswscale/ops_chain.c
@@ -42,20 +42,25 @@ void ff_sws_op_chain_free_cb(void *ptr)
}
int ff_sws_op_chain_append(SwsOpChain *chain, SwsFuncPtr func, const void *ref,
- const SwsOpPriv *priv)
+ const void *data, size_t data_size)
{
- const int idx = chain->num_impl;
- if (idx == SWS_MAX_OPS)
+ /* Ensures each SwsOpImpl is stored aligned, so that we can deref it */
+ const size_t op_size = FFALIGN(offsetof(SwsOpImpl, priv) + data_size,
+ alignof(SwsOpImpl));
+
+ if (chain->impl_size + op_size > sizeof(chain->impl))
return AVERROR(EINVAL);
if (ref && chain->num_ref >= FF_ARRAY_ELEMS(chain->ref))
return AVERROR(EINVAL);
- av_assert1(func);
- chain->impl[idx].func = func;
- chain->impl[idx].priv = *priv;
- chain->num_impl++;
+ SwsOpImpl *impl = (SwsOpImpl *) &chain->impl[chain->impl_size];
+ impl->func = func;
+ if (data_size)
+ memcpy(&impl->priv, data, data_size);
+ chain->impl_size += op_size;
if (ref)
chain->ref[chain->num_ref++] = av_refstruct_ref_c(ref);
+
return 0;
}
@@ -122,7 +127,7 @@ int ff_sws_uop_lookup(SwsContext *ctx, const SwsUOpTable *const tables[],
}
ret = ff_sws_op_chain_append(chain, res.func ? res.func : match->func,
- res.ref, &res.priv);
+ res.ref, &res.priv, sizeof(res.priv));
av_refstruct_unref(&res.ref);
if (ret < 0)
return ret;
diff --git a/libswscale/ops_chain.h b/libswscale/ops_chain.h
index f660215520..b7e88710a3 100644
--- a/libswscale/ops_chain.h
+++ b/libswscale/ops_chain.h
@@ -78,6 +78,7 @@ typedef struct 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
/**
@@ -86,9 +87,13 @@ static_assert(offsetof(SwsOpImpl, priv) == 8, "SwsOpImpl layout mismatch");
* private data for each operation.
*/
typedef struct SwsOpChain {
-#define SWS_MAX_OPS 16
- SwsOpImpl impl[SWS_MAX_OPS];
- int num_impl;
+ /* Generic data buffer. This contains a packed representation of
+ * continuation addresses and kernel private data. This is placed at
+ * the front of the struct so SIMD kernels can access it directly. */
+ DECLARE_ALIGNED_8(uint8_t, impl)[1024];
+ int impl_size;
+
+ /* Metadata for the chain */
int cpu_flags; /* set of all used CPU flags */
int over_read[4]; /* chain over-reads input by this many bytes */
int over_write[4]; /* chain over-writes output by this many bytes */
@@ -107,7 +112,7 @@ static inline void ff_sws_op_chain_free(SwsOpChain *chain)
/* Returns 0 on success, or a negative error code. */
int ff_sws_op_chain_append(SwsOpChain *chain, SwsFuncPtr func, const void *ref,
- const SwsOpPriv *priv);
+ const void *data, size_t data_size);
/**
* Attach a SwsOpChain and all metadata to a SwsCompiledOp (as out->priv).
diff --git a/libswscale/uops_backend.c b/libswscale/uops_backend.c
index 94d22e404e..305f74779b 100644
--- a/libswscale/uops_backend.c
+++ b/libswscale/uops_backend.c
@@ -111,7 +111,7 @@ static void process_c(const SwsOpExec *exec, const void *priv,
int bx_end, int y_end)
{
const SwsOpChain *chain = priv;
- const SwsOpImpl *impl = chain->impl;
+ const SwsOpImpl *impl = (const SwsOpImpl *) chain->impl;
block_t x, y, z, w; /* allocate enough space for any intermediate */
SwsOpIter iter;