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

Git pushed a commit to branch master
in repository ffmpeg.

commit c744f685410dcaf6810154cbb18a286ed9b27d9a
Author:     Niklas Haas <[email protected]>
AuthorDate: Tue Nov 3 16:59:46 2026 +0100
Commit:     Niklas Haas <[email protected]>
CommitDate: Sun Nov 8 01:48:12 2026 +0000

    swscale/ops_chain: track references instead of arbitrary free callbacks
    
    We don't really need this level of generality.
    
    Signed-off-by: Niklas Haas <[email protected]>
---
 libswscale/aarch64/ops.c | 10 ++++------
 libswscale/ops_chain.c   | 24 ++++++++++++------------
 libswscale/ops_chain.h   | 11 +++++++----
 libswscale/uops_tmpl.c   | 18 ++++++------------
 libswscale/x86/ops.c     | 18 ++++++------------
 5 files changed, 35 insertions(+), 46 deletions(-)

diff --git a/libswscale/aarch64/ops.c b/libswscale/aarch64/ops.c
index ec11d0d871..d0412909ad 100644
--- a/libswscale/aarch64/ops.c
+++ b/libswscale/aarch64/ops.c
@@ -98,17 +98,14 @@ static int aarch64_setup_linear(const 
SwsAArch64OpImplParams *p,
         }
     }
 
-    res->priv.ptr = coeffs;
-    res->free = ff_op_priv_unref;
-
+    res->ref = res->priv.ptr = coeffs;
     return 0;
 }
 
 /*********************************************************************/
 static int aarch64_setup_dither(const SwsUOp *uop, SwsImplResult *res)
 {
-    res->priv.ptr = av_refstruct_ref(uop->data.ptr);
-    res->free = ff_op_priv_unref;
+    res->ref = res->priv.ptr = av_refstruct_ref(uop->data.ptr);
     return 0;
 }
 
@@ -186,7 +183,8 @@ static int compile_uops_aarch64(SwsContext *ctx, const 
SwsUOpList *uops,
         ret = aarch64_setup(&uops->ops[i], &params, &res);
         if (ret < 0)
             goto error;
-        ret = ff_sws_op_chain_append(chain, func, res.free, &res.priv);
+        ret = ff_sws_op_chain_append(chain, func, res.ref, &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 ff48ede4a2..9eb4b242dc 100644
--- a/libswscale/ops_chain.c
+++ b/libswscale/ops_chain.c
@@ -20,6 +20,7 @@
 
 #include "libavutil/avassert.h"
 #include "libavutil/mem.h"
+#include "libavutil/refstruct.h"
 
 #include "ops_chain.h"
 
@@ -34,26 +35,27 @@ void ff_sws_op_chain_free_cb(void *ptr)
         return;
 
     SwsOpChain *chain = ptr;
-    for (int i = 0; i < chain->num_impl + 1; i++) {
-        if (chain->free[i])
-            chain->free[i](&chain->impl[i].priv);
-    }
+    for (int i = 0; i < chain->num_ref; i++)
+        av_refstruct_unref(&chain->ref[i]);
 
     av_free(chain);
 }
 
-int ff_sws_op_chain_append(SwsOpChain *chain, SwsFuncPtr func,
-                           void (*free)(SwsOpPriv *), const SwsOpPriv *priv)
+int ff_sws_op_chain_append(SwsOpChain *chain, SwsFuncPtr func, const void *ref,
+                           const SwsOpPriv *priv)
 {
     const int idx = chain->num_impl;
     if (idx == SWS_MAX_OPS)
         return AVERROR(EINVAL);
+    if (ref && chain->num_ref >= FF_ARRAY_ELEMS(chain->ref))
+        return AVERROR(EINVAL);
 
     av_assert1(func);
     chain->impl[idx].cont = func;
     chain->impl[idx + 1].priv = *priv;
-    chain->free[idx + 1] = free;
     chain->num_impl++;
+    if (ref)
+        chain->ref[chain->num_ref++] = av_refstruct_ref_c(ref);
     return 0;
 }
 
@@ -120,12 +122,10 @@ 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.free, &res.priv);
-    if (ret < 0) {
-        if (res.free)
-            res.free(&res.priv);
+                                 res.ref, &res.priv);
+    av_refstruct_unref(&res.ref);
+    if (ret < 0)
         return ret;
-    }
 
     for (int i = 0; i < 4; i++) {
         chain->over_read[i]  = FFMAX(chain->over_read[i],  res.over_read[i]);
diff --git a/libswscale/ops_chain.h b/libswscale/ops_chain.h
index 6fd9a57a94..01c96bbd43 100644
--- a/libswscale/ops_chain.h
+++ b/libswscale/ops_chain.h
@@ -85,11 +85,14 @@ static_assert(offsetof(SwsOpImpl, priv) == 16, "SwsOpImpl 
layout mismatch");
 typedef struct SwsOpChain {
 #define SWS_MAX_OPS 16
     SwsOpImpl impl[SWS_MAX_OPS + 1]; /* reserve extra space for the entrypoint 
*/
-    void (*free[SWS_MAX_OPS + 1])(SwsOpPriv *);
     int num_impl;
     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 */
+
+    /* Extra references owned by each kernel */
+    const void *ref[16];
+    int num_ref;
 } SwsOpChain;
 
 SwsOpChain *ff_sws_op_chain_alloc(void);
@@ -100,8 +103,8 @@ 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,
-                           void (*free)(SwsOpPriv *), const SwsOpPriv *priv);
+int ff_sws_op_chain_append(SwsOpChain *chain, SwsFuncPtr func, const void *ref,
+                           const SwsOpPriv *priv);
 
 /**
  * Attach a SwsOpChain and all metadata to a SwsCompiledOp (as out->priv).
@@ -120,9 +123,9 @@ typedef struct SwsImplParams {
 typedef struct SwsImplResult {
     SwsFuncPtr func; /* overrides `SwsUOpEntry.func` if non-NULL */
     SwsOpPriv priv; /* private data for this implementation instance */
-    void (*free)(SwsOpPriv *priv); /* free function for `priv` */
     int over_read[4];  /* implementation over-reads input by this many bytes */
     int over_write[4]; /* implementation over-writes output by this many bytes 
*/
+    const void *ref; /* external data backing `priv`, ownership passes to 
caller */
 } SwsImplResult;
 
 typedef struct SwsUOpEntry {
diff --git a/libswscale/uops_tmpl.c b/libswscale/uops_tmpl.c
index 0ba058c8da..80c6391f5d 100644
--- a/libswscale/uops_tmpl.c
+++ b/libswscale/uops_tmpl.c
@@ -262,9 +262,8 @@ DECL_SETUP(setup_filter_v, params, out)
     for (int i = 0; i < filter->num_weights; i++)
         weights[i] = (float) filter->weights[i] / SWS_FILTER_SCALE;
 
-    out->priv.ptr = weights;
+    out->ref = out->priv.ptr = weights;
     out->priv.i32[2] = filter->filter_size;
-    out->free = ff_op_priv_unref;
     return 0;
 }
 
@@ -317,9 +316,8 @@ DECL_SETUP(setup_filter_h, params, out)
     static_assert(SWS_FILTER_PAD_ROWS >= SWS_BLOCK_SIZE,
                   "filter weights contain sufficient padding for block 
over-read");
 
-    out->priv.ptr = av_refstruct_ref(filter->weights);
+    out->ref = out->priv.ptr = av_refstruct_ref(filter->weights);
     out->priv.i32[2] = filter->filter_size;
-    out->free = ff_op_priv_unref;
     return 0;
 }
 
@@ -726,8 +724,7 @@ DECL_SETUP(setup_dither, params, out)
     const int size = 1 << dither->size_log2;
     if (size >= SWS_BLOCK_SIZE) {
         /* No extra padding needed */
-        out->priv.ptr = av_refstruct_ref(uop->data.ptr);
-        out->free = ff_op_priv_unref;
+        out->ref = out->priv.ptr = av_refstruct_ref(uop->data.ptr);
         return 0;
     }
 
@@ -736,8 +733,7 @@ DECL_SETUP(setup_dither, params, out)
     pixel_t *matrix = ff_refstruct_calloc(height, sizeof(pixel_t) * stride);
     if (!matrix)
         return AVERROR(ENOMEM);
-    out->priv.ptr = matrix;
-    out->free = ff_op_priv_unref;
+    out->ref = out->priv.ptr = matrix;
 
     /* Pad to multiple of block size. We don't need extra padding for the
      * height because ff_sws_dither_height() already includes any padding
@@ -805,11 +801,10 @@ DECL_SETUP(setup_linear, params, out)
         c.k[i] = uop->data.mat4x5[i][4].px;
     }
 
-    out->priv.ptr = av_refstruct_allocz(sizeof(c));
+    out->ref = out->priv.ptr = av_refstruct_allocz(sizeof(c));
     if (!out->priv.ptr)
         return AVERROR(ENOMEM);
     memcpy(out->priv.ptr, &c, sizeof(c));
-    out->free = ff_op_priv_unref;
     return 0;
 }
 
@@ -861,8 +856,7 @@ SWS_FOR_STRUCT(PX, LINEAR, DECL_ENTRY, .setup = 
fn(setup_linear) )
 DECL_SETUP(setup_lut3d, params, out)
 {
     const SwsLut3D *lut = params->uop->data.lut3d;
-    out->priv.ptr = (void *) av_refstruct_ref_c(lut);
-    out->free = ff_op_priv_unref;
+    out->ref = out->priv.ptr = (void *) av_refstruct_ref_c(lut);
     return 0;
 }
 
diff --git a/libswscale/x86/ops.c b/libswscale/x86/ops.c
index 719d19e65b..3c6e783bd6 100644
--- a/libswscale/x86/ops.c
+++ b/libswscale/x86/ops.c
@@ -57,9 +57,8 @@ static int setup_filter_v(const SwsImplParams *params, 
SwsImplResult *out)
     for (int i = 0; i < filter->num_weights; i++)
         weights[i] = (float) filter->weights[i] / SWS_FILTER_SCALE;
 
-    out->priv.ptr = weights;
+    out->ref = out->priv.ptr = weights;
     out->priv.uptr[1] = filter->filter_size;
-    out->free = ff_op_priv_unref;
     return 0;
 }
 
@@ -150,9 +149,8 @@ static int setup_filter_h(const SwsImplParams *params, 
SwsImplResult *out)
         }
     }
 
-    out->priv.ptr = weights.ptr;
+    out->ref = out->priv.ptr = weights.ptr;
     out->priv.uptr[1] = aligned_size;
-    out->free = ff_op_priv_unref;
 
     for (int i = 0; i < 4; i++) {
         if (uop->mask & SWS_COMP(i))
@@ -237,9 +235,8 @@ static int setup_filter_h_4x4(const SwsImplParams *params, 
SwsImplResult *out)
         }
     }
 
-    out->priv.ptr = weights.ptr;
+    out->ref = out->priv.ptr = weights.ptr;
     out->priv.uptr[1] = aligned_size * sizeof_weights;
-    out->free = ff_op_priv_unref;
 
     for (int i = 0; i < 4; i++) {
         if (uop->mask & SWS_COMP(i))
@@ -272,8 +269,7 @@ static int setup_clear(const SwsImplParams *params, 
SwsImplResult *out)
 
 static int setup_dither(const SwsImplParams *params, SwsImplResult *out)
 {
-    out->priv.ptr = av_refstruct_ref(params->uop->data.ptr);
-    out->free = ff_op_priv_unref;
+    out->ref = out->priv.ptr = av_refstruct_ref(params->uop->data.ptr);
     return 0;
 }
 
@@ -298,19 +294,17 @@ static int setup_linear(const SwsImplParams *params, 
SwsImplResult *out)
 {
     const SwsUOp *uop = params->uop;
     if (uop->type == SWS_PIXEL_F32) {
-        out->priv.ptr = av_refstruct_allocz(sizeof(uop->data.mat4x5));
+        out->ref = out->priv.ptr = 
av_refstruct_allocz(sizeof(uop->data.mat4x5));
         if (!out->priv.ptr)
             return AVERROR(ENOMEM);
         memcpy(out->priv.ptr, uop->data.mat4x5, sizeof(uop->data.mat4x5));
-        out->free = ff_op_priv_unref;
         return 0;
     }
 
     uint8_t *mat = av_refstruct_allocz(4 * 5 * 16); /* one lane per component 
*/
     if (!mat)
         return AVERROR(ENOMEM);
-    out->priv.ptr = mat;
-    out->free = ff_op_priv_unref;
+    out->ref = out->priv.ptr = mat;
 
     for (int i = 0; i < 4; i++) {
         for (int j = 0; j < 5; j++) {

-- 
To stop receiving notification emails like this one, please contact
[email protected].
_______________________________________________
ffmpeg-cvslog mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to