Commit 85fe84e5e3 for ffmpeg

commit 85fe84e5e3c3b62e930323956ad473538c04fd32
Author: Niklas Haas <git@haasn.dev>
Date:   Tue Nov 3 17:21:39 2026 +0100

    swscale/ops: allocate external kernel data as refstructs

    Having a common allocation scheme for external kernel data will
    allow us to get rid of SwsOpPriv.

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

diff --git a/libswscale/aarch64/ops.c b/libswscale/aarch64/ops.c
index 1018c9b9dc..ec11d0d871 100644
--- a/libswscale/aarch64/ops.c
+++ b/libswscale/aarch64/ops.c
@@ -74,7 +74,7 @@ static int aarch64_setup_linear(const SwsAArch64OpImplParams *p,
      */
     const int num_vregs = linear_num_vregs(p);
     av_assert0(num_vregs <= 4);
-    void *coeffs = av_malloc(num_vregs * 16);
+    void *coeffs = av_refstruct_allocz(num_vregs * 16);
     if (!coeffs)
         return AVERROR(ENOMEM);

@@ -99,7 +99,7 @@ static int aarch64_setup_linear(const SwsAArch64OpImplParams *p,
     }

     res->priv.ptr = coeffs;
-    res->free = ff_op_priv_free;
+    res->free = ff_op_priv_unref;

     return 0;
 }
diff --git a/libswscale/ops_chain.h b/libswscale/ops_chain.h
index f68b3f72ad..6fd9a57a94 100644
--- a/libswscale/ops_chain.h
+++ b/libswscale/ops_chain.h
@@ -25,6 +25,7 @@
 #include "libavutil/mem.h"

 #include "ops_internal.h"
+#include "swscale_internal.h"

 /**
  * Helpers for SIMD implementations based on chained kernels, using a
diff --git a/libswscale/uops_tmpl.c b/libswscale/uops_tmpl.c
index 15e41297b0..0ba058c8da 100644
--- a/libswscale/uops_tmpl.c
+++ b/libswscale/uops_tmpl.c
@@ -255,7 +255,7 @@ DECL_SETUP(setup_filter_v, params, out)
                   ">8 byte pointers not supported");

     /* Pre-convert weights to float */
-    float *weights = av_calloc(filter->num_weights, sizeof(float));
+    float *weights = ff_refstruct_calloc(filter->num_weights, sizeof(float));
     if (!weights)
         return AVERROR(ENOMEM);

@@ -264,7 +264,7 @@ DECL_SETUP(setup_filter_v, params, out)

     out->priv.ptr = weights;
     out->priv.i32[2] = filter->filter_size;
-    out->free = ff_op_priv_free;
+    out->free = ff_op_priv_unref;
     return 0;
 }

@@ -733,11 +733,11 @@ DECL_SETUP(setup_dither, params, out)

     const int stride = FFMAX(size, SWS_BLOCK_SIZE);
     const int height = ff_sws_dither_height(dither);
-    pixel_t *matrix = av_malloc(sizeof(pixel_t) * height * stride);
+    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_free;
+    out->free = ff_op_priv_unref;

     /* 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,9 +805,12 @@ DECL_SETUP(setup_linear, params, out)
         c.k[i] = uop->data.mat4x5[i][4].px;
     }

-    out->priv.ptr = av_memdup(&c, sizeof(c));
-    out->free = ff_op_priv_free;
-    return out->priv.ptr ? 0 : AVERROR(ENOMEM);
+    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;
 }

 /**
diff --git a/libswscale/x86/ops.c b/libswscale/x86/ops.c
index 8c0b14ab0d..719d19e65b 100644
--- a/libswscale/x86/ops.c
+++ b/libswscale/x86/ops.c
@@ -50,7 +50,7 @@ static int setup_filter_v(const SwsImplParams *params, SwsImplResult *out)
                   ">8 byte pointers not supported");

     /* Pre-convert weights to float */
-    float *weights = av_calloc(filter->num_weights, sizeof(float));
+    float *weights = ff_refstruct_calloc(filter->num_weights, sizeof(float));
     if (!weights)
         return AVERROR(ENOMEM);

@@ -59,7 +59,7 @@ static int setup_filter_v(const SwsImplParams *params, SwsImplResult *out)

     out->priv.ptr = weights;
     out->priv.uptr[1] = filter->filter_size;
-    out->free = ff_op_priv_free;
+    out->free = ff_op_priv_unref;
     return 0;
 }

@@ -100,7 +100,7 @@ static int setup_filter_h(const SwsImplParams *params, SwsImplResult *out)
     } weights;

     const int sizeof_weight = hscale_sizeof_weight(uop);
-    weights.ptr = av_calloc(line_size, sizeof_weight * aligned_size);
+    weights.ptr = ff_refstruct_calloc(line_size, sizeof_weight * aligned_size);
     if (!weights.ptr)
         return AVERROR(ENOMEM);

@@ -152,7 +152,7 @@ static int setup_filter_h(const SwsImplParams *params, SwsImplResult *out)

     out->priv.ptr = weights.ptr;
     out->priv.uptr[1] = aligned_size;
-    out->free = ff_op_priv_free;
+    out->free = ff_op_priv_unref;

     for (int i = 0; i < 4; i++) {
         if (uop->mask & SWS_COMP(i))
@@ -205,7 +205,7 @@ static int setup_filter_h_4x4(const SwsImplParams *params, SwsImplResult *out)
         float *f32;
     } weights;

-    weights.ptr = av_calloc(line_size, aligned_size * sizeof_weights);
+    weights.ptr = ff_refstruct_calloc(line_size, aligned_size * sizeof_weights);
     if (!weights.ptr)
         return AVERROR(ENOMEM);

@@ -239,7 +239,7 @@ static int setup_filter_h_4x4(const SwsImplParams *params, SwsImplResult *out)

     out->priv.ptr = weights.ptr;
     out->priv.uptr[1] = aligned_size * sizeof_weights;
-    out->free = ff_op_priv_free;
+    out->free = ff_op_priv_unref;

     for (int i = 0; i < 4; i++) {
         if (uop->mask & SWS_COMP(i))
@@ -298,16 +298,19 @@ static int setup_linear(const SwsImplParams *params, SwsImplResult *out)
 {
     const SwsUOp *uop = params->uop;
     if (uop->type == SWS_PIXEL_F32) {
-        out->priv.ptr = av_memdup(uop->data.mat4x5, sizeof(uop->data.mat4x5));
-        out->free = ff_op_priv_free;
-        return out->priv.ptr ? 0 : AVERROR(ENOMEM);
+        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_malloc(4 * 5 * 16); /* one lane per component */
+    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_free;
+    out->free = ff_op_priv_unref;

     for (int i = 0; i < 4; i++) {
         for (int j = 0; j < 5; j++) {