From: Niklas Haas <ffmpeg@haasn.xyz> To: ffmpeg-devel@ffmpeg.org Cc: Niklas Haas <git@haasn.dev> Subject: [FFmpeg-devel] [PATCH v6 09/18] swscale/ops_internal: add internal ops backend API Date: Wed, 11 Jun 2025 14:47:15 +0200 Message-ID: <20250611124805.73196-10-ffmpeg@haasn.xyz> (raw) In-Reply-To: <20250611124805.73196-1-ffmpeg@haasn.xyz> From: Niklas Haas <git@haasn.dev> This adds an internal API for ops backends, which are responsible for compiling op lists into executable functions. --- libswscale/ops.c | 65 +++++++++++++++++++++++ libswscale/ops_internal.h | 108 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 173 insertions(+) create mode 100644 libswscale/ops_internal.h diff --git a/libswscale/ops.c b/libswscale/ops.c index f8f2e20840..101ceda568 100644 --- a/libswscale/ops.c +++ b/libswscale/ops.c @@ -25,9 +25,22 @@ #include "libavutil/refstruct.h" #include "ops.h" +#include "ops_internal.h" + +const SwsOpBackend * const ff_sws_op_backends[] = { + NULL +}; + +const int ff_sws_num_op_backends = FF_ARRAY_ELEMS(ff_sws_op_backends) - 1; #define Q(N) ((AVRational) { N, 1 }) +#define RET(x) \ + do { \ + if ((ret = (x)) < 0) \ + return ret; \ + } while (0) + const char *ff_sws_pixel_type_name(SwsPixelType type) { switch (type) { @@ -522,3 +535,55 @@ void ff_sws_op_list_print(void *log, int lev, const SwsOpList *ops) av_log(log, lev, " (X = unused, + = exact, 0 = zero)\n"); } + +int ff_sws_ops_compile_backend(SwsContext *ctx, const SwsOpBackend *backend, + const SwsOpList *ops, SwsCompiledOp *out) +{ + SwsOpList *copy, rest; + SwsCompiledOp compiled = {0}; + int ret = 0; + + copy = ff_sws_op_list_duplicate(ops); + if (!copy) + return AVERROR(ENOMEM); + + /* Ensure these are always set during compilation */ + ff_sws_op_list_update_comps(copy); + + /* Make an on-stack copy of `ops` to ensure we can still properly clean up + * the copy afterwards */ + rest = *copy; + + ret = backend->compile(ctx, &rest, &compiled); + if (ret == AVERROR(ENOTSUP)) { + av_log(ctx, AV_LOG_TRACE, "Backend '%s' does not support operations:\n", backend->name); + ff_sws_op_list_print(ctx, AV_LOG_TRACE, &rest); + } else if (ret < 0) { + av_log(ctx, AV_LOG_ERROR, "Failed to compile operations: %s\n", av_err2str(ret)); + ff_sws_op_list_print(ctx, AV_LOG_ERROR, &rest); + } else { + *out = compiled; + } + + ff_sws_op_list_free(©); + return ret; +} + +int ff_sws_ops_compile(SwsContext *ctx, const SwsOpList *ops, SwsCompiledOp *out) +{ + for (int n = 0; ff_sws_op_backends[n]; n++) { + const SwsOpBackend *backend = ff_sws_op_backends[n]; + if (ff_sws_ops_compile_backend(ctx, backend, ops, out) < 0) + continue; + + av_log(ctx, AV_LOG_VERBOSE, "Compiled using backend '%s': " + "block size = %d, over-read = %d, over-write = %d, cpu flags = 0x%x\n", + backend->name, out->block_size, out->over_read, out->over_write, + out->cpu_flags); + return 0; + } + + av_log(ctx, AV_LOG_WARNING, "No backend found for operations:\n"); + ff_sws_op_list_print(ctx, AV_LOG_WARNING, ops); + return AVERROR(ENOTSUP); +} diff --git a/libswscale/ops_internal.h b/libswscale/ops_internal.h new file mode 100644 index 0000000000..9fd866430b --- /dev/null +++ b/libswscale/ops_internal.h @@ -0,0 +1,108 @@ +/** + * Copyright (C) 2025 Niklas Haas + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef SWSCALE_OPS_INTERNAL_H +#define SWSCALE_OPS_INTERNAL_H + +#include "libavutil/mem_internal.h" + +#include "ops.h" + +/** + * Global execution context for all compiled functions. + * + * Note: This struct is hard-coded in assembly, so do not change the layout + * without updating the corresponding assembly definitions. + */ +typedef struct SwsOpExec { + /* The data pointers point to the first pixel to process */ + DECLARE_ALIGNED_32(const uint8_t, *in[4]); + DECLARE_ALIGNED_32(uint8_t, *out[4]); + + /* Separation between lines in bytes */ + DECLARE_ALIGNED_32(ptrdiff_t, in_stride[4]); + DECLARE_ALIGNED_32(ptrdiff_t, out_stride[4]); + + /* Extra metadata, may or may not be useful */ + int32_t width, height; /* Overall image dimensions */ + int32_t slice_y, slice_h; /* Start and height of current slice */ + int32_t pixel_bits_in; /* Bits per input pixel */ + int32_t pixel_bits_out; /* Bits per output pixel */ +} SwsOpExec; + +static_assert(sizeof(SwsOpExec) == 16 * sizeof(void *) + 8 * sizeof(int32_t), + "SwsOpExec layout mismatch"); + +/** + * Process a given range of pixel blocks. + * + * Note: `bx_start` and `bx_end` are in units of `SwsCompiledOp.block_size`. + */ +typedef void (*SwsOpFunc)(const SwsOpExec *exec, const void *priv, + int bx_start, int y_start, int bx_end, int y_end); + +#define SWS_DECL_FUNC(NAME) \ + void NAME(const SwsOpExec *, const void *, int, int, int, int) + +typedef struct SwsCompiledOp { + SwsOpFunc func; + + int block_size; /* number of pixels processed per iteration */ + int over_read; /* implementation over-reads input by this many bytes */ + int over_write; /* implementation over-writes output by this many bytes */ + int cpu_flags; /* active set of CPU flags (informative) */ + + /* Arbitrary private data */ + void *priv; + void (*free)(void *priv); +} SwsCompiledOp; + +typedef struct SwsOpBackend { + const char *name; /* Descriptive name for this backend */ + + /** + * Compile an operation list to an implementation chain. May modify `ops` + * freely; the original list will be freed automatically by the caller. + * + * Returns 0 or a negative error code. + */ + int (*compile)(SwsContext *ctx, SwsOpList *ops, SwsCompiledOp *out); +} SwsOpBackend; + +/* List of all backends, terminated by NULL */ +extern const SwsOpBackend *const ff_sws_op_backends[]; +extern const int ff_sws_num_op_backends; /* excludes terminating NULL */ + +/** + * Attempt to compile a list of operations using a specific backend. + * + * Returns 0 on success, or a negative error code on failure. + */ +int ff_sws_ops_compile_backend(SwsContext *ctx, const SwsOpBackend *backend, + const SwsOpList *ops, SwsCompiledOp *out); + +/** + * Compile a list of operations using the best available backend. + * + * Returns 0 on success, or a negative error code on failure. + */ +int ff_sws_ops_compile(SwsContext *ctx, const SwsOpList *ops, SwsCompiledOp *out); + +#endif -- 2.49.0 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
next prev parent reply other threads:[~2025-06-11 12:52 UTC|newest] Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top 2025-06-11 12:47 [FFmpeg-devel] [PATCH v6 00/18] swscale: new ops framework Niklas Haas 2025-06-11 12:47 ` [FFmpeg-devel] [PATCH v6 01/18] swscale/graph: pass per-pass image pointers to setup() Niklas Haas 2025-06-11 12:47 ` [FFmpeg-devel] [PATCH v6 02/18] swscale/format: rename legacy format conversion table Niklas Haas 2025-06-11 12:47 ` [FFmpeg-devel] [PATCH v6 03/18] swscale/format: add ff_fmt_clear() Niklas Haas 2025-06-11 12:47 ` [FFmpeg-devel] [PATCH v6 04/18] tests/checkasm: increase number of runs in between measurements Niklas Haas 2025-06-11 12:47 ` [FFmpeg-devel] [PATCH v6 05/18] tests/checkasm: generalize DEF_CHECKASM_CHECK_FUNC to floats Niklas Haas 2025-06-11 12:47 ` [FFmpeg-devel] [PATCH v6 06/18] swscale: add SWS_UNSTABLE flag Niklas Haas 2025-06-11 12:47 ` [FFmpeg-devel] [PATCH v6 07/18] swscale/ops: introduce new low level framework Niklas Haas 2025-06-11 12:47 ` [FFmpeg-devel] [PATCH v6 08/18] swscale/optimizer: add high-level ops optimizer Niklas Haas 2025-06-11 12:47 ` Niklas Haas [this message] 2025-06-11 12:47 ` [FFmpeg-devel] [PATCH v6 10/18] swscale/ops: add dispatch layer Niklas Haas 2025-06-11 12:47 ` [FFmpeg-devel] [PATCH v6 11/18] swscale/optimizer: add packed shuffle solver Niklas Haas 2025-06-11 12:47 ` [FFmpeg-devel] [PATCH v6 12/18] swscale/ops_chain: add internal abstraction for kernel linking Niklas Haas 2025-06-11 12:47 ` [FFmpeg-devel] [PATCH v6 13/18] swscale/ops_backend: add reference backend basend on C templates Niklas Haas 2025-06-11 12:47 ` [FFmpeg-devel] [PATCH v6 14/18] swscale/ops_memcpy: add 'memcpy' backend for plane->plane copies Niklas Haas 2025-06-11 12:47 ` [FFmpeg-devel] [PATCH v6 15/18] swscale/x86: add SIMD backend Niklas Haas 2025-06-11 12:47 ` [FFmpeg-devel] [PATCH v6 16/18] tests/checkasm: add checkasm tests for swscale ops Niklas Haas 2025-06-11 12:47 ` [FFmpeg-devel] [PATCH v6 17/18] swscale/format: add new format decode/encode logic Niklas Haas 2025-06-11 12:47 ` [FFmpeg-devel] [PATCH v6 18/18] swscale/graph: allow experimental use of new format handler Niklas Haas 2025-06-11 17:59 ` [FFmpeg-devel] [PATCH v6 00/18] swscale: new ops framework Niklas Haas 2025-06-16 12:31 ` Niklas Haas
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20250611124805.73196-10-ffmpeg@haasn.xyz \ --to=ffmpeg@haasn.xyz \ --cc=ffmpeg-devel@ffmpeg.org \ --cc=git@haasn.dev \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel This inbox may be cloned and mirrored by anyone: git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git # If you have public-inbox 1.1+ installed, you may # initialize and index your mirror using the following commands: public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \ ffmpegdev@gitmailbox.com public-inbox-index ffmpegdev Example config snippet for mirrors. AGPL code for this site: git clone https://public-inbox.org/public-inbox.git