/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 | int scale = 0; |
35 | 0 | for (int i = 0; i < dst / src; i++) |
36 | 0 | scale = scale << src * 8 | 1; |
37 | 0 | return Q(scale); |
38 | 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 |
39 | | |
40 | | static inline void ff_sws_pack_op_decode(const SwsOp *op, uint64_t mask[4], int shift[4]) |
41 | 0 | { |
42 | 0 | int size = 0; |
43 | 0 | for (int i = 0; i < 4; i++) |
44 | 0 | size += op->pack.pattern[i]; |
45 | 0 | for (int i = 0; i < 4; i++) { |
46 | 0 | const int bits = op->pack.pattern[i]; |
47 | 0 | mask[i] = (UINT64_C(1) << bits) - 1; |
48 | 0 | shift[i] = (i ? shift[i - 1] : size) - bits; |
49 | 0 | } |
50 | 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 |
51 | | |
52 | | /** |
53 | | * Global execution context for all compiled functions. |
54 | | * |
55 | | * Note: This struct is hard-coded in assembly, so do not change the layout |
56 | | * without updating the corresponding assembly definitions. |
57 | | */ |
58 | | typedef struct SwsOpExec { |
59 | | /* The data pointers point to the first pixel to process */ |
60 | | const uint8_t *in[4]; |
61 | | uint8_t *out[4]; |
62 | | |
63 | | /* Separation between lines in bytes */ |
64 | | ptrdiff_t in_stride[4]; |
65 | | ptrdiff_t out_stride[4]; |
66 | | |
67 | | /* Pointer bump, difference between stride and processed line size */ |
68 | | ptrdiff_t in_bump[4]; |
69 | | ptrdiff_t out_bump[4]; |
70 | | |
71 | | /* Extra metadata, may or may not be useful */ |
72 | | int32_t width, height; /* Overall image dimensions */ |
73 | | int32_t slice_y, slice_h; /* Start and height of current slice */ |
74 | | int32_t block_size_in; /* Size of a block of pixels in bytes */ |
75 | | int32_t block_size_out; |
76 | | } SwsOpExec; |
77 | | |
78 | | static_assert(sizeof(SwsOpExec) == 24 * sizeof(void *) + 6 * sizeof(int32_t), |
79 | | "SwsOpExec layout mismatch"); |
80 | | |
81 | | /** |
82 | | * Process a given range of pixel blocks. |
83 | | * |
84 | | * Note: `bx_start` and `bx_end` are in units of `SwsCompiledOp.block_size`. |
85 | | */ |
86 | | typedef void (*SwsOpFunc)(const SwsOpExec *exec, const void *priv, |
87 | | int bx_start, int y_start, int bx_end, int y_end); |
88 | | |
89 | | #define SWS_DECL_FUNC(NAME) \ |
90 | 0 | void NAME(const SwsOpExec *, const void *, int, int, int, int) |
91 | | |
92 | | typedef struct SwsCompiledOp { |
93 | | SwsOpFunc func; |
94 | | |
95 | | int block_size; /* number of pixels processed per iteration */ |
96 | | int over_read; /* implementation over-reads input by this many bytes */ |
97 | | int over_write; /* implementation over-writes output by this many bytes */ |
98 | | int cpu_flags; /* active set of CPU flags (informative) */ |
99 | | |
100 | | /* Arbitrary private data */ |
101 | | void *priv; |
102 | | void (*free)(void *priv); |
103 | | } SwsCompiledOp; |
104 | | |
105 | | typedef struct SwsOpBackend { |
106 | | const char *name; /* Descriptive name for this backend */ |
107 | | |
108 | | /** |
109 | | * Compile an operation list to an implementation chain. May modify `ops` |
110 | | * freely; the original list will be freed automatically by the caller. |
111 | | * |
112 | | * Returns 0 or a negative error code. |
113 | | */ |
114 | | int (*compile)(SwsContext *ctx, SwsOpList *ops, SwsCompiledOp *out); |
115 | | } SwsOpBackend; |
116 | | |
117 | | /* List of all backends, terminated by NULL */ |
118 | | extern const SwsOpBackend *const ff_sws_op_backends[]; |
119 | | |
120 | | /** |
121 | | * Attempt to compile a list of operations using a specific backend. |
122 | | * |
123 | | * Returns 0 on success, or a negative error code on failure. |
124 | | */ |
125 | | int ff_sws_ops_compile_backend(SwsContext *ctx, const SwsOpBackend *backend, |
126 | | const SwsOpList *ops, SwsCompiledOp *out); |
127 | | |
128 | | /** |
129 | | * Compile a list of operations using the best available backend. |
130 | | * |
131 | | * Returns 0 on success, or a negative error code on failure. |
132 | | */ |
133 | | int ff_sws_ops_compile(SwsContext *ctx, const SwsOpList *ops, SwsCompiledOp *out); |
134 | | |
135 | | /** |
136 | | * "Solve" an op list into a fixed shuffle mask, with an optional ability to |
137 | | * also directly clear the output value (for e.g. rgb24 -> rgb0). This can |
138 | | * accept any operation chain that only consists of the following operations: |
139 | | * |
140 | | * - SWS_OP_READ (non-planar, non-fractional) |
141 | | * - SWS_OP_SWIZZLE |
142 | | * - SWS_OP_SWAP_BYTES |
143 | | * - SWS_OP_CLEAR to zero (when clear_val is specified) |
144 | | * - SWS_OP_CONVERT (integer expand) |
145 | | * - SWS_OP_WRITE (non-planar, non-fractional) |
146 | | * |
147 | | * Basically, any operation that purely consists of moving around and reordering |
148 | | * bytes within a single plane, can be turned into a shuffle mask. |
149 | | * |
150 | | * @param ops The operation list to decompose. |
151 | | * @param shuffle The output shuffle mask. |
152 | | * @param size The size (in bytes) of the output shuffle mask. |
153 | | * @param clear_val If nonzero, this index will be used to clear the output. |
154 | | * @param read_bytes Returns the number of bytes read per shuffle iteration. |
155 | | * @param write_bytes Returns the number of bytes written per shuffle iteration. |
156 | | * |
157 | | * @return The number of pixels processed per iteration, or a negative error |
158 | | code; in particular AVERROR(ENOTSUP) for unsupported operations. |
159 | | */ |
160 | | int ff_sws_solve_shuffle(const SwsOpList *ops, uint8_t shuffle[], int size, |
161 | | uint8_t clear_val, int *read_bytes, int *write_bytes); |
162 | | |
163 | | #endif /* SWSCALE_OPS_INTERNAL_H */ |