This is an automated email from the git hooks/post-receive script.

Git pushed a commit to branch master
in repository ffmpeg.

commit 1e268fbedf893ed827453c13f0b139ca67f0696e
Author:     Niklas Haas <[email protected]>
AuthorDate: Wed Apr 8 14:39:39 2026 +0200
Commit:     Niklas Haas <[email protected]>
CommitDate: Tue Jun 9 18:27:20 2026 +0200

    swscale/ops_chain: add uop-based helpers to assemble SwsOpChain
    
    This will eventually replace the existing op_match() and
    ff_sws_op_compile_tables(), but I've decided to introduce it separately 
first
    so that I can incrementally update the backends to use the new API, at the
    cost of some temporary code duplication.
    
    Signed-off-by: Niklas Haas <[email protected]>
---
 libswscale/ops_chain.c | 100 +++++++++++++++++++++++++++++++++++++++++++++++++
 libswscale/ops_chain.h |  30 +++++++++++++--
 2 files changed, 126 insertions(+), 4 deletions(-)

diff --git a/libswscale/ops_chain.c b/libswscale/ops_chain.c
index 8b32da7eeb..1c3e0c3677 100644
--- a/libswscale/ops_chain.c
+++ b/libswscale/ops_chain.c
@@ -193,6 +193,7 @@ int ff_sws_op_compile_tables(SwsContext *ctx, const 
SwsOpTable *const tables[],
 
     for (int n = 0; n < num_tables; n++) {
         const SwsOpTable *table = tables[n];
+        av_assert0(!table->uops);
         if (table->block_size && table->block_size != block_size ||
             table->cpu_flags & ~cpu_flags)
             continue;
@@ -295,3 +296,102 @@ int ff_sws_setup_clear(const SwsImplParams *params, 
SwsImplResult *out)
 
     return 0;
 }
+
+int ff_sws_uop_lookup(SwsContext *ctx, const SwsOpTable *const tables[],
+                      int num_tables, const SwsUOp *uop, const int block_size,
+                      SwsOpChain *chain)
+{
+    const unsigned cpu_flags = av_get_cpu_flags();
+    const SwsOpEntry *match = NULL;
+    int ret;
+
+    SwsImplParams params = {
+        .ctx = ctx,
+        .uop = uop
+    };
+
+    for (int n = 0; !match && n < num_tables; n++) {
+        const SwsOpTable *table = params.table = tables[n];
+        av_assert0(table->uops);
+        if (table->block_size && table->block_size != block_size ||
+            table->cpu_flags & ~cpu_flags)
+            continue;
+
+        for (int i = 0; table->entries[i]; i++) {
+            const SwsOpEntry *entry = table->entries[i];
+            const SwsUOp entry_uop = {
+                .uop  = entry->uop,
+                .type = entry->type,
+                .mask = entry->mask,
+                .par  = entry->par,
+            };
+
+            if (ff_sws_uop_cmp(uop, &entry_uop) != 0)
+                continue;
+            if (entry->check && !entry->check(&params))
+                continue;
+
+            match = entry;
+            break;
+        }
+    }
+
+    if (!match) {
+        char name[64];
+        ff_sws_uop_name(uop, name);
+        av_log(ctx, AV_LOG_DEBUG, "No implementation found for: %s\n", name);
+        return AVERROR(ENOTSUP);
+    }
+
+    SwsImplResult res = {0};
+    if (match->setup) {
+        ret = match->setup(&params, &res);
+        if (ret < 0)
+            return ret;
+    }
+
+    ret = ff_sws_op_chain_append(chain, res.func ? res.func : match->func,
+                                 res.free, &res.priv);
+    if (ret < 0) {
+        if (res.free)
+            res.free(&res.priv);
+        return ret;
+    }
+
+    chain->cpu_flags |= params.table->cpu_flags;
+    chain->over_read  = FFMAX(chain->over_read,  res.over_read);
+    chain->over_write = FFMAX(chain->over_write, res.over_write);
+    return 0;
+}
+
+int ff_sws_setup_scalar(const SwsImplParams *params, SwsImplResult *out)
+{
+    const SwsUOp *uop = params->uop;
+    const SwsPixel scalar = uop->data.scalar;
+    switch (uop->type) {
+    case SWS_PIXEL_U8:  out->priv.u8[0]  = scalar.u8;  break;
+    case SWS_PIXEL_U16: out->priv.u16[0] = scalar.u16; break;
+    case SWS_PIXEL_U32: out->priv.u32[0] = scalar.u32; break;
+    case SWS_PIXEL_F32: out->priv.f32[0] = scalar.f32; break;
+    default: return AVERROR(EINVAL);
+    }
+
+    return 0;
+}
+
+int ff_sws_setup_vec4(const SwsImplParams *params, SwsImplResult *out)
+{
+    const SwsUOp *uop = params->uop;
+    for (int i = 0; i < 4; i++) {
+        const SwsPixel vi = uop->data.vec4[i];
+        switch (uop->type) {
+        case SWS_PIXEL_U8:  out->priv.u8[i]  = vi.u8;  break;
+        case SWS_PIXEL_U16: out->priv.u16[i] = vi.u16; break;
+        case SWS_PIXEL_U32: out->priv.u32[i] = vi.u32; break;
+        case SWS_PIXEL_F32: out->priv.f32[i] = vi.f32; break;
+        default: return AVERROR(EINVAL);
+        }
+    }
+
+    return 0;
+}
diff --git a/libswscale/ops_chain.h b/libswscale/ops_chain.h
index dcd9a9fc74..031b172c2c 100644
--- a/libswscale/ops_chain.h
+++ b/libswscale/ops_chain.h
@@ -104,7 +104,10 @@ int ff_sws_op_chain_append(SwsOpChain *chain, SwsFuncPtr 
func,
 
 typedef struct SwsImplParams {
     const SwsOpTable *table;
-    const SwsOp *op;
+    union {
+        const SwsUOp *uop;
+        const SwsOp *op;
+    };
     SwsContext *ctx;
 } SwsImplParams;
 
@@ -118,12 +121,16 @@ typedef struct SwsImplResult {
 
 typedef struct SwsOpEntry {
     /* Kernel metadata; reduced size subset of SwsOp */
-    SwsOpType op;
+    union {
+        SwsOpType op;
+        SwsUOpType uop;
+    };
     SwsPixelType type;
-    SwsCompMask mask; /* mask of active components (after operation) */
-    bool flexible; /* if true, only the type and op are matched */
+    SwsCompMask mask;
+    bool flexible; /* if true, only the type and op are matched (for ops only) 
*/
 
     union { /* extra data defining the operation, unless `flexible` is true */
+        SwsUOpParams   par;
         SwsReadWriteOp rw;
         SwsPackOp      pack;
         SwsSwizzleOp   swizzle;
@@ -146,6 +153,10 @@ int ff_sws_setup_scale(const SwsImplParams *params, 
SwsImplResult *out);
 int ff_sws_setup_clamp(const SwsImplParams *params, SwsImplResult *out);
 int ff_sws_setup_clear(const SwsImplParams *params, SwsImplResult *out);
 
+/* Setup helpers for SwsUOp data */
+int ff_sws_setup_scalar(const SwsImplParams *params, SwsImplResult *out);
+int ff_sws_setup_vec4(const SwsImplParams *params, SwsImplResult *out);
+
 static inline void ff_op_priv_free(SwsOpPriv *priv)
 {
     av_freep(&priv->ptr);
@@ -159,6 +170,7 @@ static inline void ff_op_priv_unref(SwsOpPriv *priv)
 struct SwsOpTable {
     unsigned cpu_flags;   /* required CPU flags for this table */
     int block_size;       /* fixed block size of this table */
+    bool uops;            /* if true, entries are uops, not ops */
     const SwsOpEntry *entries[]; /* terminated by NULL */
 };
 
@@ -172,4 +184,14 @@ int ff_sws_op_compile_tables(SwsContext *ctx, const 
SwsOpTable *const tables[],
                              int num_tables, const SwsOp *op,
                              const int block_size, SwsOpChain *chain);
 
+/**
+ * "Compile" a single uop by looking it up in a list of fixed size uop tables,
+ * in decreasing order of preference.
+ *
+ * Returns 0 or a negative error code.
+ */
+int ff_sws_uop_lookup(SwsContext *ctx, const SwsOpTable *const tables[],
+                      int num_tables, const SwsUOp *uop, const int block_size,
+                      SwsOpChain *chain);
+
 #endif

_______________________________________________
ffmpeg-cvslog mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to