This is an automated email from the git hooks/post-receive script. Git pushed a commit to branch master in repository ffmpeg.
commit e4abfb8e519895c7fd84425430016cb6fabd424b Author: Niklas Haas <[email protected]> AuthorDate: Tue Feb 24 12:54:27 2026 +0100 Commit: Niklas Haas <[email protected]> CommitDate: Thu Feb 26 10:15:52 2026 +0000 swscale/ops_backend: avoid UB from incorrect function signature Annoying C-ism; we can't overload the function type even though they will always be pointers. We can't even get away with using (void *) in the function signature, despite casts to void * being technically valid. Avoid the issue altogether by just moving the process loop into the type-specific template altogether, and just referring to the correct compiled process function at runtime. Hopefully, the compiler should be able to optimize these into a single implementation. GCC, at least, compiles these down into a single implementation plus three stubs that just jmp to the correct one. Signed-off-by: Niklas Haas <[email protected]> --- libswscale/ops_backend.c | 36 ++++++++++++------------------------ libswscale/ops_tmpl_common.c | 24 ++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 24 deletions(-) diff --git a/libswscale/ops_backend.c b/libswscale/ops_backend.c index a503139016..449ba8c975 100644 --- a/libswscale/ops_backend.c +++ b/libswscale/ops_backend.c @@ -48,29 +48,6 @@ typedef float f32block_t[SWS_BLOCK_SIZE]; # include "ops_tmpl_float.c" #undef BIT_DEPTH -static void process(const SwsOpExec *exec, const void *priv, - const int bx_start, const int y_start, int bx_end, int y_end) -{ - const SwsOpChain *chain = priv; - const SwsOpImpl *impl = chain->impl; - u32block_t x, y, z, w; /* allocate enough space for any intermediate */ - - SwsOpIter iterdata; - SwsOpIter *iter = &iterdata; /* for CONTINUE() macro to work */ - - for (iter->y = y_start; iter->y < y_end; iter->y++) { - for (int i = 0; i < 4; i++) { - iter->in[i] = exec->in[i] + (iter->y - y_start) * exec->in_stride[i]; - iter->out[i] = exec->out[i] + (iter->y - y_start) * exec->out_stride[i]; - } - - for (int block = bx_start; block < bx_end; block++) { - iter->x = block * SWS_BLOCK_SIZE; - CONTINUE(u32block_t, x, y, z, w); - } - } -} - static int compile(SwsContext *ctx, SwsOpList *ops, SwsCompiledOp *out) { int ret; @@ -79,6 +56,9 @@ static int compile(SwsContext *ctx, SwsOpList *ops, SwsCompiledOp *out) if (!chain) return AVERROR(ENOMEM); + av_assert0(ops->num_ops > 0); + const SwsPixelType read_type = ops->ops[0].type; + static const SwsOpTable *const tables[] = { &bitfn(op_table_int, u8), &bitfn(op_table_int, u16), @@ -96,12 +76,20 @@ static int compile(SwsContext *ctx, SwsOpList *ops, SwsCompiledOp *out) } *out = (SwsCompiledOp) { - .func = process, .block_size = SWS_BLOCK_SIZE, .cpu_flags = chain->cpu_flags, .priv = chain, .free = ff_sws_op_chain_free_cb, }; + + switch (read_type) { + case SWS_PIXEL_U8: out->func = process_u8; break; + case SWS_PIXEL_U16: out->func = process_u16; break; + case SWS_PIXEL_U32: out->func = process_u32; break; + case SWS_PIXEL_F32: out->func = process_f32; break; + default: return AVERROR(EINVAL); + } + return 0; } diff --git a/libswscale/ops_tmpl_common.c b/libswscale/ops_tmpl_common.c index 7cfec4e3f6..c0e0d9f3fb 100644 --- a/libswscale/ops_tmpl_common.c +++ b/libswscale/ops_tmpl_common.c @@ -175,3 +175,27 @@ WRAP_COMMON_PATTERNS(scale, .setup = ff_sws_setup_q, .flexible = true, ); + +static void fn(process)(const SwsOpExec *exec, const void *priv, + const int bx_start, const int y_start, + int bx_end, int y_end) +{ + const SwsOpChain *chain = priv; + const SwsOpImpl *impl = chain->impl; + u32block_t x, y, z, w; /* allocate enough space for any intermediate */ + + SwsOpIter iterdata; + SwsOpIter *iter = &iterdata; /* for CONTINUE() macro to work */ + + for (iter->y = y_start; iter->y < y_end; iter->y++) { + for (int i = 0; i < 4; i++) { + iter->in[i] = exec->in[i] + (iter->y - y_start) * exec->in_stride[i]; + iter->out[i] = exec->out[i] + (iter->y - y_start) * exec->out_stride[i]; + } + + for (int block = bx_start; block < bx_end; block++) { + iter->x = block * SWS_BLOCK_SIZE; + CONTINUE(block_t, (void *) x, (void *) y, (void *) z, (void *) w); + } + } +} _______________________________________________ ffmpeg-cvslog mailing list -- [email protected] To unsubscribe send an email to [email protected]
