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], ¶ms, &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]
