/src/ffmpeg/libswscale/ops_internal.h
Line | Count | Source |
1 | | /** |
2 | | * Copyright (C) 2025 Niklas Haas |
3 | | * |
4 | | * This file is part of FFmpeg. |
5 | | * |
6 | | * FFmpeg is free software; you can redistribute it and/or |
7 | | * modify it under the terms of the GNU Lesser General Public |
8 | | * License as published by the Free Software Foundation; either |
9 | | * version 2.1 of the License, or (at your option) any later version. |
10 | | * |
11 | | * FFmpeg is distributed in the hope that it will be useful, |
12 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
14 | | * Lesser General Public License for more details. |
15 | | * |
16 | | * You should have received a copy of the GNU Lesser General Public |
17 | | * License along with FFmpeg; if not, write to the Free Software |
18 | | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
19 | | */ |
20 | | |
21 | | #ifndef SWSCALE_OPS_INTERNAL_H |
22 | | #define SWSCALE_OPS_INTERNAL_H |
23 | | |
24 | | #include "libavutil/mem_internal.h" |
25 | | |
26 | | #include "ops.h" |
27 | | |
28 | 0 | #define Q(N) ((AVRational) { N, 1 }) |
29 | | |
30 | | static inline AVRational ff_sws_pixel_expand(SwsPixelType from, SwsPixelType to) |
31 | 0 | { |
32 | 0 | const int src = ff_sws_pixel_type_size(from); |
33 | 0 | const int dst = ff_sws_pixel_type_size(to); |
34 | 0 | if (src > dst) |
35 | 0 | return Q(0); |
36 | 0 | int scale = 1; |
37 | 0 | for (int i = 1; i < dst / src; i++) |
38 | 0 | scale = (scale << (src * 8)) | 1; |
39 | 0 | return Q(scale); |
40 | 0 | } Unexecuted instantiation: format.c:ff_sws_pixel_expand Unexecuted instantiation: ops.c:ff_sws_pixel_expand Unexecuted instantiation: ops_backend.c:ff_sws_pixel_expand Unexecuted instantiation: ops_chain.c:ff_sws_pixel_expand Unexecuted instantiation: ops_memcpy.c:ff_sws_pixel_expand Unexecuted instantiation: ops_optimizer.c:ff_sws_pixel_expand |
41 | | |
42 | | static inline void ff_sws_pack_op_decode(const SwsOp *op, uint64_t mask[4], int shift[4]) |
43 | 0 | { |
44 | 0 | int size = 0; |
45 | 0 | for (int i = 0; i < 4; i++) |
46 | 0 | size += op->pack.pattern[i]; |
47 | 0 | for (int i = 0; i < 4; i++) { |
48 | 0 | const int bits = op->pack.pattern[i]; |
49 | 0 | mask[i] = (UINT64_C(1) << bits) - 1; |
50 | 0 | shift[i] = (i ? shift[i - 1] : size) - bits; |
51 | 0 | } |
52 | 0 | } Unexecuted instantiation: format.c:ff_sws_pack_op_decode Unexecuted instantiation: ops.c:ff_sws_pack_op_decode Unexecuted instantiation: ops_backend.c:ff_sws_pack_op_decode Unexecuted instantiation: ops_chain.c:ff_sws_pack_op_decode Unexecuted instantiation: ops_memcpy.c:ff_sws_pack_op_decode Unexecuted instantiation: ops_optimizer.c:ff_sws_pack_op_decode |
53 | | |
54 | | /** |
55 | | * Global execution context for all compiled functions. |
56 | | * |
57 | | * Note: This struct is hard-coded in assembly, so do not change the layout |
58 | | * without updating the corresponding assembly definitions. |
59 | | */ |
60 | | typedef struct SwsOpExec { |
61 | | /* The data pointers point to the first pixel to process */ |
62 | | const uint8_t *in[4]; |
63 | | uint8_t *out[4]; |
64 | | |
65 | | /* Separation between lines in bytes */ |
66 | | ptrdiff_t in_stride[4]; |
67 | | ptrdiff_t out_stride[4]; |
68 | | |
69 | | /* Pointer bump, difference between stride and processed line size */ |
70 | | ptrdiff_t in_bump[4]; |
71 | | ptrdiff_t out_bump[4]; |
72 | | |
73 | | /* Extra metadata, may or may not be useful */ |
74 | | int32_t width, height; /* Overall image dimensions */ |
75 | | int32_t slice_y, slice_h; /* Start and height of current slice */ |
76 | | int32_t block_size_in; /* Size of a block of pixels in bytes */ |
77 | | int32_t block_size_out; |
78 | | } SwsOpExec; |
79 | | |
80 | | static_assert(sizeof(SwsOpExec) == 24 * sizeof(void *) + 6 * sizeof(int32_t), |
81 | | "SwsOpExec layout mismatch"); |
82 | | |
83 | | /** |
84 | | * Process a given range of pixel blocks. |
85 | | * |
86 | | * Note: `bx_start` and `bx_end` are in units of `SwsCompiledOp.block_size`. |
87 | | */ |
88 | | typedef void (*SwsOpFunc)(const SwsOpExec *exec, const void *priv, |
89 | | int bx_start, int y_start, int bx_end, int y_end); |
90 | | |
91 | | #define SWS_DECL_FUNC(NAME) \ |
92 | 0 | void NAME(const SwsOpExec *, const void *, int, int, int, int) |
93 | | |
94 | | typedef struct SwsCompiledOp { |
95 | | SwsOpFunc func; |
96 | | |
97 | | int block_size; /* number of pixels processed per iteration */ |
98 | | int over_read; /* implementation over-reads input by this many bytes */ |
99 | | int over_write; /* implementation over-writes output by this many bytes */ |
100 | | int cpu_flags; /* active set of CPU flags (informative) */ |
101 | | |
102 | | /* Arbitrary private data */ |
103 | | void *priv; |
104 | | void (*free)(void *priv); |
105 | | } SwsCompiledOp; |
106 | | |
107 | | typedef struct SwsOpBackend { |
108 | | const char *name; /* Descriptive name for this backend */ |
109 | | |
110 | | /** |
111 | | * Compile an operation list to an implementation chain. May modify `ops` |
112 | | * freely; the original list will be freed automatically by the caller. |
113 | | * |
114 | | * Returns 0 or a negative error code. |
115 | | */ |
116 | | int (*compile)(SwsContext *ctx, SwsOpList *ops, SwsCompiledOp *out); |
117 | | } SwsOpBackend; |
118 | | |
119 | | /* List of all backends, terminated by NULL */ |
120 | | extern const SwsOpBackend *const ff_sws_op_backends[]; |
121 | | |
122 | | /** |
123 | | * Attempt to compile a list of operations using a specific backend. |
124 | | * |
125 | | * Returns 0 on success, or a negative error code on failure. |
126 | | */ |
127 | | int ff_sws_ops_compile_backend(SwsContext *ctx, const SwsOpBackend *backend, |
128 | | const SwsOpList *ops, SwsCompiledOp *out); |
129 | | |
130 | | /** |
131 | | * Compile a list of operations using the best available backend. |
132 | | * |
133 | | * Returns 0 on success, or a negative error code on failure. |
134 | | */ |
135 | | int ff_sws_ops_compile(SwsContext *ctx, const SwsOpList *ops, SwsCompiledOp *out); |
136 | | |
137 | | /** |
138 | | * "Solve" an op list into a fixed shuffle mask, with an optional ability to |
139 | | * also directly clear the output value (for e.g. rgb24 -> rgb0). This can |
140 | | * accept any operation chain that only consists of the following operations: |
141 | | * |
142 | | * - SWS_OP_READ (non-planar, non-fractional) |
143 | | * - SWS_OP_SWIZZLE |
144 | | * - SWS_OP_SWAP_BYTES |
145 | | * - SWS_OP_CLEAR to zero (when clear_val is specified) |
146 | | * - SWS_OP_CONVERT (integer expand) |
147 | | * - SWS_OP_WRITE (non-planar, non-fractional) |
148 | | * |
149 | | * Basically, any operation that purely consists of moving around and reordering |
150 | | * bytes within a single plane, can be turned into a shuffle mask. |
151 | | * |
152 | | * @param ops The operation list to decompose. |
153 | | * @param shuffle The output shuffle mask. |
154 | | * @param size The size (in bytes) of the output shuffle mask. |
155 | | * @param clear_val If nonzero, this index will be used to clear the output. |
156 | | * @param read_bytes Returns the number of bytes read per shuffle iteration. |
157 | | * @param write_bytes Returns the number of bytes written per shuffle iteration. |
158 | | * |
159 | | * @return The number of pixels processed per iteration, or a negative error |
160 | | code; in particular AVERROR(ENOTSUP) for unsupported operations. |
161 | | */ |
162 | | int ff_sws_solve_shuffle(const SwsOpList *ops, uint8_t shuffle[], int size, |
163 | | uint8_t clear_val, int *read_bytes, int *write_bytes); |
164 | | |
165 | | #endif /* SWSCALE_OPS_INTERNAL_H */ |