FFmpeg
ops_dispatch.c
Go to the documentation of this file.
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 #include "libavutil/avassert.h"
22 #include "libavutil/mem.h"
23 #include "libavutil/mem_internal.h"
24 
25 #include "ops.h"
26 #include "ops_internal.h"
27 #include "ops_dispatch.h"
28 
29 typedef struct SwsOpPass {
37  int planes_in;
41  int idx_in[4];
42  int idx_out[4];
43  bool memcpy_in;
44  bool memcpy_out;
45 } SwsOpPass;
46 
48  const SwsOpList *ops, SwsCompiledOp *out)
49 {
50  SwsOpList *copy;
51  SwsCompiledOp compiled = {0};
52  int ret = 0;
53 
55  if (!copy)
56  return AVERROR(ENOMEM);
57 
58  /* Ensure these are always set during compilation */
60 
61  ret = backend->compile(ctx, copy, &compiled);
62  if (ret < 0) {
63  int msg_lev = ret == AVERROR(ENOTSUP) ? AV_LOG_TRACE : AV_LOG_ERROR;
64  av_log(ctx, msg_lev, "Backend '%s' failed to compile operations: %s\n",
65  backend->name, av_err2str(ret));
66  } else {
67  *out = compiled;
68  }
69 
71  return ret;
72 }
73 
75 {
76  for (int n = 0; ff_sws_op_backends[n]; n++) {
77  const SwsOpBackend *backend = ff_sws_op_backends[n];
78  if (ops->src.hw_format != backend->hw_format ||
79  ops->dst.hw_format != backend->hw_format)
80  continue;
81  if (ff_sws_ops_compile_backend(ctx, backend, ops, out) < 0)
82  continue;
83 
84  av_log(ctx, AV_LOG_VERBOSE, "Compiled using backend '%s': "
85  "block size = %d, over-read = %d, over-write = %d, cpu flags = 0x%x\n",
86  backend->name, out->block_size, out->over_read, out->over_write,
87  out->cpu_flags);
88  return 0;
89  }
90 
91  av_log(ctx, AV_LOG_WARNING, "No backend found for operations:\n");
93  return AVERROR(ENOTSUP);
94 }
95 
96 static void op_pass_free(void *ptr)
97 {
98  SwsOpPass *p = ptr;
99  if (!p)
100  return;
101 
102  if (p->comp.free)
103  p->comp.free(p->comp.priv);
104 
105  av_free(p);
106 }
107 
108 static inline void get_row_data(const SwsOpPass *p, const int y,
109  const uint8_t *in[4], uint8_t *out[4])
110 {
111  const SwsOpExec *base = &p->exec_base;
112  for (int i = 0; i < p->planes_in; i++)
113  in[i] = base->in[i] + (y >> base->in_sub_y[i]) * base->in_stride[i];
114  for (int i = 0; i < p->planes_out; i++)
115  out[i] = base->out[i] + (y >> base->out_sub_y[i]) * base->out_stride[i];
116 }
117 
118 static void op_pass_setup(const SwsFrame *out, const SwsFrame *in,
119  const SwsPass *pass)
120 {
121  const AVPixFmtDescriptor *indesc = av_pix_fmt_desc_get(in->format);
122  const AVPixFmtDescriptor *outdesc = av_pix_fmt_desc_get(out->format);
123 
124  SwsOpPass *p = pass->priv;
125  SwsOpExec *exec = &p->exec_base;
126  const SwsCompiledOp *comp = &p->comp;
127  const int block_size = comp->block_size;
128  p->num_blocks = (pass->width + block_size - 1) / block_size;
129 
130  /* Set up main loop parameters */
131  const int aligned_w = p->num_blocks * block_size;
132  const int safe_width = (p->num_blocks - 1) * block_size;
133  const int tail_size = pass->width - safe_width;
134  p->tail_off_in = safe_width * p->pixel_bits_in >> 3;
135  p->tail_off_out = safe_width * p->pixel_bits_out >> 3;
136  p->tail_size_in = tail_size * p->pixel_bits_in >> 3;
137  p->tail_size_out = tail_size * p->pixel_bits_out >> 3;
138  p->memcpy_in = false;
139  p->memcpy_out = false;
140 
141  for (int i = 0; i < p->planes_in; i++) {
142  const int idx = p->idx_in[i];
143  const int chroma = idx == 1 || idx == 2;
144  const int sub_x = chroma ? indesc->log2_chroma_w : 0;
145  const int sub_y = chroma ? indesc->log2_chroma_h : 0;
146  const int plane_w = (aligned_w + sub_x) >> sub_x;
147  const int plane_pad = (comp->over_read + sub_x) >> sub_x;
148  const int plane_size = plane_w * p->pixel_bits_in >> 3;
149  if (comp->slice_align)
150  p->memcpy_in |= plane_size + plane_pad > in->linesize[idx];
151  exec->in[i] = in->data[idx];
152  exec->in_stride[i] = in->linesize[idx];
153  exec->in_sub_y[i] = sub_y;
154  exec->in_sub_x[i] = sub_x;
155  }
156 
157  for (int i = 0; i < p->planes_out; i++) {
158  const int idx = p->idx_out[i];
159  const int chroma = idx == 1 || idx == 2;
160  const int sub_x = chroma ? outdesc->log2_chroma_w : 0;
161  const int sub_y = chroma ? outdesc->log2_chroma_h : 0;
162  const int plane_w = (aligned_w + sub_x) >> sub_x;
163  const int plane_pad = (comp->over_write + sub_x) >> sub_x;
164  const int plane_size = plane_w * p->pixel_bits_out >> 3;
165  if (comp->slice_align)
166  p->memcpy_out |= plane_size + plane_pad > out->linesize[idx];
167  exec->out[i] = out->data[idx];
168  exec->out_stride[i] = out->linesize[idx];
169  exec->out_sub_y[i] = sub_y;
170  exec->out_sub_x[i] = sub_x;
171  }
172 
173  /* Pre-fill pointer bump for the main section only; this value does not
174  * matter at all for the tail / last row handlers because they only ever
175  * process a single line */
176  const int blocks_main = p->num_blocks - p->memcpy_out;
177  for (int i = 0; i < 4; i++) {
178  exec->in_bump[i] = exec->in_stride[i] - blocks_main * exec->block_size_in;
179  exec->out_bump[i] = exec->out_stride[i] - blocks_main * exec->block_size_out;
180  }
181 
182  exec->in_frame = in;
183  exec->out_frame = out;
184 }
185 
186 /* Dispatch kernel over the last column of the image using memcpy */
187 static av_always_inline void
189  const bool copy_out, const bool copy_in,
190  int y, const int h)
191 {
192  DECLARE_ALIGNED_64(uint8_t, tmp)[2][4][sizeof(uint32_t[128])];
193 
194  const SwsOpExec *base = &p->exec_base;
195  const SwsCompiledOp *comp = &p->comp;
196  const int tail_size_in = p->tail_size_in;
197  const int tail_size_out = p->tail_size_out;
198  const int bx = p->num_blocks - 1;
199 
200  const uint8_t *in_data[4];
201  uint8_t *out_data[4];
202  get_row_data(p, y, in_data, out_data);
203 
204  for (int i = 0; i < p->planes_in; i++) {
205  in_data[i] += p->tail_off_in;
206  if (copy_in) {
207  exec->in[i] = (void *) tmp[0][i];
208  exec->in_stride[i] = sizeof(tmp[0][i]);
209  } else {
210  exec->in[i] = in_data[i];
211  }
212  }
213 
214  for (int i = 0; i < p->planes_out; i++) {
215  out_data[i] += p->tail_off_out;
216  if (copy_out) {
217  exec->out[i] = (void *) tmp[1][i];
218  exec->out_stride[i] = sizeof(tmp[1][i]);
219  } else {
220  exec->out[i] = out_data[i];
221  }
222  }
223 
224  for (int y_end = y + h; y < y_end; y++) {
225  if (copy_in) {
226  for (int i = 0; i < p->planes_in; i++) {
227  av_assert2(tmp[0][i] + tail_size_in < (uint8_t *) tmp[1]);
228  memcpy(tmp[0][i], in_data[i], tail_size_in);
229  in_data[i] += base->in_stride[i]; /* exec->in_stride was clobbered */
230  }
231  }
232 
233  comp->func(exec, comp->priv, bx, y, p->num_blocks, y + 1);
234 
235  if (copy_out) {
236  for (int i = 0; i < p->planes_out; i++) {
237  av_assert2(tmp[1][i] + tail_size_out < (uint8_t *) tmp[2]);
238  memcpy(out_data[i], tmp[1][i], tail_size_out);
239  out_data[i] += base->out_stride[i];
240  }
241  }
242 
243  for (int i = 0; i < 4; i++) {
244  if (!copy_in && exec->in[i])
245  exec->in[i] += exec->in_stride[i];
246  if (!copy_out && exec->out[i])
247  exec->out[i] += exec->out_stride[i];
248  }
249  }
250 }
251 
252 static void op_pass_run(const SwsFrame *out, const SwsFrame *in, const int y,
253  const int h, const SwsPass *pass)
254 {
255  const SwsOpPass *p = pass->priv;
256  const SwsCompiledOp *comp = &p->comp;
257 
258  /* Fill exec metadata for this slice */
259  DECLARE_ALIGNED_32(SwsOpExec, exec) = p->exec_base;
260  exec.slice_y = y;
261  exec.slice_h = h;
262 
263  /**
264  * To ensure safety, we need to consider the following:
265  *
266  * 1. We can overread the input, unless this is the last line of an
267  * unpadded buffer. All defined operations can handle arbitrary pixel
268  * input, so overread of arbitrary data is fine.
269  *
270  * 2. We can overwrite the output, as long as we don't write more than the
271  * amount of pixels that fit into one linesize. So we always need to
272  * memcpy the last column on the output side if unpadded.
273  *
274  * 3. For the last row, we also need to memcpy the remainder of the input,
275  * to avoid reading past the end of the buffer. Note that since we know
276  * the run() function is called on stripes of the same buffer, we don't
277  * need to worry about this for the end of a slice.
278  */
279 
280  const int last_slice = y + h == pass->height;
281  const bool memcpy_in = last_slice && p->memcpy_in;
282  const bool memcpy_out = p->memcpy_out;
283  const int num_blocks = p->num_blocks;
284  const int blocks_main = num_blocks - memcpy_out;
285  const int h_main = h - memcpy_in;
286 
287  /* Handle main section */
288  get_row_data(p, y, exec.in, exec.out);
289  comp->func(&exec, comp->priv, 0, y, blocks_main, y + h_main);
290 
291  if (memcpy_in) {
292  /* Safe part of last row */
293  get_row_data(p, y + h_main, exec.in, exec.out);
294  comp->func(&exec, comp->priv, 0, y + h_main, num_blocks - 1, y + h);
295  }
296 
297  /* Handle last column via memcpy, takes over `exec` so call these last */
298  if (memcpy_out)
299  handle_tail(p, &exec, true, false, y, h_main);
300  if (memcpy_in)
301  handle_tail(p, &exec, memcpy_out, true, y + h_main, 1);
302 }
303 
304 static int rw_planes(const SwsOp *op)
305 {
306  return op->rw.packed ? 1 : op->rw.elems;
307 }
308 
309 static int rw_pixel_bits(const SwsOp *op)
310 {
311  const int elems = op->rw.packed ? op->rw.elems : 1;
312  const int size = ff_sws_pixel_type_size(op->type);
313  const int bits = 8 >> op->rw.frac;
314  av_assert1(bits >= 1);
315  return elems * size * bits;
316 }
317 
318 static int compile(SwsGraph *graph, const SwsOpList *ops,
319  const SwsFormat *dst, SwsPass *input, SwsPass **output)
320 {
321  SwsContext *ctx = graph->ctx;
322  SwsOpPass *p = av_mallocz(sizeof(*p));
323  if (!p)
324  return AVERROR(ENOMEM);
325 
326  int ret = ff_sws_ops_compile(ctx, ops, &p->comp);
327  if (ret < 0)
328  goto fail;
329 
330  const SwsOp *read = ff_sws_op_list_input(ops);
331  const SwsOp *write = ff_sws_op_list_output(ops);
332  p->planes_in = rw_planes(read);
333  p->planes_out = rw_planes(write);
334  p->pixel_bits_in = rw_pixel_bits(read);
335  p->pixel_bits_out = rw_pixel_bits(write);
336  p->exec_base = (SwsOpExec) {
337  .width = dst->width,
338  .height = dst->height,
339  .block_size_in = p->comp.block_size * p->pixel_bits_in >> 3,
340  .block_size_out = p->comp.block_size * p->pixel_bits_out >> 3,
341  };
342 
343  for (int i = 0; i < 4; i++) {
344  p->idx_in[i] = i < p->planes_in ? ops->order_src.in[i] : -1;
345  p->idx_out[i] = i < p->planes_out ? ops->order_dst.in[i] : -1;
346  }
347 
348  SwsPass *pass;
349  ret = ff_sws_graph_add_pass(graph, dst->format, dst->width, dst->height,
350  input, p->comp.slice_align, p, op_pass_run,
351  &pass);
352  if (ret < 0)
353  goto fail;
354 
355  pass->setup = op_pass_setup;
356  pass->free = op_pass_free;
357 
358  *output = pass;
359  return 0;
360 
361 fail:
362  op_pass_free(p);
363  return ret;
364 }
365 
367  const SwsFormat *dst, SwsPass *input, SwsPass **output)
368 {
369  SwsContext *ctx = graph->ctx;
370  int ret;
371 
372  /* Check if the whole operation graph is an end-to-end no-op */
373  if (ff_sws_op_list_is_noop(ops)) {
374  *output = input;
375  return 0;
376  }
377 
378  const SwsOp *read = ff_sws_op_list_input(ops);
379  const SwsOp *write = ff_sws_op_list_output(ops);
380  if (!read || !write) {
381  av_log(ctx, AV_LOG_ERROR, "First and last operations must be a read "
382  "and write, respectively.\n");
383  return AVERROR(EINVAL);
384  }
385 
386  if (flags & SWS_OP_FLAG_OPTIMIZE) {
388  if (ret < 0)
389  return ret;
390  } else {
392  }
393 
394  return compile(graph, ops, dst, input, output);
395 }
flags
const SwsFlags flags[]
Definition: swscale.c:61
rw_planes
static int rw_planes(const SwsOp *op)
Definition: ops_dispatch.c:304
ff_sws_op_list_free
void ff_sws_op_list_free(SwsOpList **p_ops)
Definition: ops.c:501
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:216
SwsGraph::ctx
SwsContext * ctx
Definition: graph.h:104
SwsPass
Represents a single filter pass in the scaling graph.
Definition: graph.h:63
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
handle_tail
static av_always_inline void handle_tail(const SwsOpPass *p, SwsOpExec *exec, const bool copy_out, const bool copy_in, int y, const int h)
Definition: ops_dispatch.c:188
SwsOpPass::idx_in
int idx_in[4]
Definition: ops_dispatch.c:41
SwsOpPass::tail_size_out
int tail_size_out
Definition: ops_dispatch.c:36
ff_sws_op_list_duplicate
SwsOpList * ff_sws_op_list_duplicate(const SwsOpList *ops)
Returns a duplicate of ops, or NULL on OOM.
Definition: ops.c:515
mem_internal.h
out
static FILE * out
Definition: movenc.c:55
SwsOpPass::memcpy_in
bool memcpy_in
Definition: ops_dispatch.c:43
comp
static void comp(unsigned char *dst, ptrdiff_t dst_stride, unsigned char *src, ptrdiff_t src_stride, int add)
Definition: eamad.c:79
SwsOpExec::in_bump
ptrdiff_t in_bump[4]
Definition: ops_dispatch.h:45
ff_sws_op_list_input
const SwsOp * ff_sws_op_list_input(const SwsOpList *ops)
Returns the input operation for a given op list, or NULL if there is none (e.g.
Definition: ops.c:544
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:3456
SwsOpExec::out_stride
ptrdiff_t out_stride[4]
Definition: ops_dispatch.h:42
SwsOpExec::in
const uint8_t * in[4]
Definition: ops_dispatch.h:37
SwsOpPass::num_blocks
int num_blocks
Definition: ops_dispatch.c:32
ff_sws_ops_compile
int ff_sws_ops_compile(SwsContext *ctx, const SwsOpList *ops, SwsCompiledOp *out)
Compile a list of operations using the best available backend.
Definition: ops_dispatch.c:74
output
filter_frame For filters that do not use the this method is called when a frame is pushed to the filter s input It can be called at any time except in a reentrant way If the input frame is enough to produce output
Definition: filter_design.txt:226
ops.h
SwsOpExec::block_size_in
int32_t block_size_in
Definition: ops_dispatch.h:51
chroma
static av_always_inline void chroma(WaveformContext *s, AVFrame *in, AVFrame *out, int component, int intensity, int offset_y, int offset_x, int column, int mirror, int jobnr, int nb_jobs)
Definition: vf_waveform.c:1639
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:226
base
uint8_t base
Definition: vp3data.h:128
ops_dispatch.h
SwsPass::free
void(* free)(void *priv)
Optional private state and associated free() function.
Definition: graph.h:96
SwsOpExec::in_stride
ptrdiff_t in_stride[4]
Definition: ops_dispatch.h:41
SwsOpBackend::name
const char * name
Definition: ops_internal.h:56
SwsOpPass::idx_out
int idx_out[4]
Definition: ops_dispatch.c:42
ff_sws_pixel_type_size
int ff_sws_pixel_type_size(SwsPixelType type)
Definition: ops.c:63
DECLARE_ALIGNED_64
#define DECLARE_ALIGNED_64(t, v)
Definition: mem_internal.h:114
SwsPass::width
int width
Definition: graph.h:73
ff_sws_op_list_print
void ff_sws_op_list_print(void *log, int lev, int lev_extra, const SwsOpList *ops)
Print out the contents of an operation list.
Definition: ops.c:728
ff_sws_op_backends
const SwsOpBackend *const ff_sws_op_backends[]
Definition: ops.c:36
SwsFrame::data
uint8_t * data[4]
Definition: format.h:190
ff_sws_compile_pass
int ff_sws_compile_pass(SwsGraph *graph, SwsOpList *ops, int flags, const SwsFormat *dst, SwsPass *input, SwsPass **output)
Resolves an operation list to a graph pass.
Definition: ops_dispatch.c:366
fail
#define fail()
Definition: checkasm.h:219
SwsOpBackend::compile
int(* compile)(SwsContext *ctx, SwsOpList *ops, SwsCompiledOp *out)
Compile an operation list to an implementation chain.
Definition: ops_internal.h:64
SwsOpBackend::hw_format
enum AVPixelFormat hw_format
If NONE, backend only supports software frames.
Definition: ops_internal.h:71
SwsFrame
Represents a view into a single field of frame data.
Definition: format.h:188
avassert.h
AV_LOG_TRACE
#define AV_LOG_TRACE
Extremely verbose debugging, useful for libav* development.
Definition: log.h:236
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:210
SwsFrame::format
enum AVPixelFormat format
Definition: format.h:197
SwsPass::priv
void * priv
Definition: graph.h:97
op
static int op(uint8_t **dst, const uint8_t *dst_end, GetByteContext *gb, int pixel, int count, int *x, int width, int linesize)
Perform decode operation.
Definition: anm.c:76
SwsOpExec::out_frame
const SwsFrame * out_frame
Definition: ops_dispatch.h:60
bits
uint8_t bits
Definition: vp3data.h:128
ctx
static AVFormatContext * ctx
Definition: movenc.c:49
AVPixFmtDescriptor::log2_chroma_w
uint8_t log2_chroma_w
Amount to shift the luma width right to find the chroma width.
Definition: pixdesc.h:80
ff_sws_op_list_output
const SwsOp * ff_sws_op_list_output(const SwsOpList *ops)
Returns the output operation for a given op list, or NULL if there is none.
Definition: ops.c:553
av_mallocz
#define av_mallocz(s)
Definition: tableprint_vlc.h:31
SwsOpPass::comp
SwsCompiledOp comp
Definition: ops_dispatch.c:30
SwsOpBackend
Definition: ops_internal.h:55
tmp
static uint8_t tmp[40]
Definition: aes_ctr.c:52
SwsOpExec
Copyright (C) 2026 Niklas Haas.
Definition: ops_dispatch.h:35
ff_sws_op_list_is_noop
bool ff_sws_op_list_is_noop(const SwsOpList *ops)
Returns whether an op list represents a true no-op operation, i.e.
Definition: ops.c:591
op_pass_free
static void op_pass_free(void *ptr)
Definition: ops_dispatch.c:96
rw_pixel_bits
static int rw_pixel_bits(const SwsOp *op)
Definition: ops_dispatch.c:309
SwsOpList::order_dst
SwsSwizzleOp order_dst
Definition: ops.h:230
SwsPass::height
int height
Definition: graph.h:73
SwsOpExec::block_size_out
int32_t block_size_out
Definition: ops_dispatch.h:52
copy
static void copy(const float *p1, float *p2, const int length)
Definition: vf_vaguedenoiser.c:186
dst
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition: dsp.h:87
SwsOpExec::in_sub_x
uint8_t in_sub_x[4]
Definition: ops_dispatch.h:56
i
#define i(width, name, range_min, range_max)
Definition: cbs_h264.c:63
av_err2str
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition: error.h:122
size
int size
Definition: twinvq_data.h:10344
SwsOpList::src
SwsFormat src
Definition: ops.h:227
ff_sws_graph_add_pass
int ff_sws_graph_add_pass(SwsGraph *graph, enum AVPixelFormat fmt, int width, int height, SwsPass *input, int align, void *priv, sws_filter_run_t run, SwsPass **out_pass)
Allocate and add a new pass to the filter graph.
Definition: graph.c:107
ff_sws_op_list_update_comps
void ff_sws_op_list_update_comps(SwsOpList *ops)
Infer + propagate known information about components.
Definition: ops.c:241
SwsFormat
Definition: format.h:77
SWS_OP_FLAG_OPTIMIZE
@ SWS_OP_FLAG_OPTIMIZE
Definition: ops.h:306
input
and forward the test the status of outputs and forward it to the corresponding return FFERROR_NOT_READY If the filters stores internally one or a few frame for some input
Definition: filter_design.txt:172
SwsOpPass::planes_in
int planes_in
Definition: ops_dispatch.c:37
SwsOpExec::out
uint8_t * out[4]
Definition: ops_dispatch.h:38
ff_sws_op_list_optimize
int ff_sws_op_list_optimize(SwsOpList *ops)
Fuse compatible and eliminate redundant operations, as well as replacing some operations with more ef...
Definition: ops_optimizer.c:283
av_assert2
#define av_assert2(cond)
assert() equivalent, that does lie in speed critical code.
Definition: avassert.h:68
SwsOpPass::pixel_bits_out
int pixel_bits_out
Definition: ops_dispatch.c:40
SwsOpPass::planes_out
int planes_out
Definition: ops_dispatch.c:38
SwsOpList::order_src
SwsSwizzleOp order_src
Definition: ops.h:230
SwsOpPass::tail_size_in
int tail_size_in
Definition: ops_dispatch.c:35
av_assert1
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
Definition: avassert.h:58
av_always_inline
#define av_always_inline
Definition: attributes.h:63
DECLARE_ALIGNED_32
#define DECLARE_ALIGNED_32(t, v)
Definition: mem_internal.h:113
ops_internal.h
SwsOpPass
Copyright (C) 2025 Niklas Haas.
Definition: ops_dispatch.c:29
SwsOp
Definition: ops.h:186
SwsOpExec::out_sub_y
uint8_t out_sub_y[4]
Definition: ops_dispatch.h:55
SwsOpExec::out_sub_x
uint8_t out_sub_x[4]
Definition: ops_dispatch.h:56
SwsOpExec::in_frame
const SwsFrame * in_frame
Definition: ops_dispatch.h:59
ret
ret
Definition: filter_design.txt:187
SwsPass::setup
void(* setup)(const SwsFrame *out, const SwsFrame *in, const SwsPass *pass)
Called once from the main thread before running the filter.
Definition: graph.h:91
SwsOpList::dst
SwsFormat dst
Definition: ops.h:227
SwsCompiledOp
Definition: ops_dispatch.h:80
op_pass_setup
static void op_pass_setup(const SwsFrame *out, const SwsFrame *in, const SwsPass *pass)
Definition: ops_dispatch.c:118
compile
static int compile(SwsGraph *graph, const SwsOpList *ops, const SwsFormat *dst, SwsPass *input, SwsPass **output)
Definition: ops_dispatch.c:318
SwsFormat::hw_format
enum AVPixelFormat hw_format
Definition: format.h:81
Windows::Graphics::DirectX::Direct3D11::p
IDirect3DDxgiInterfaceAccess _COM_Outptr_ void ** p
Definition: vsrc_gfxcapture_winrt.hpp:53
ff_sws_ops_compile_backend
int ff_sws_ops_compile_backend(SwsContext *ctx, const SwsOpBackend *backend, const SwsOpList *ops, SwsCompiledOp *out)
Attempt to compile a list of operations using a specific backend.
Definition: ops_dispatch.c:47
SwsOpPass::exec_base
SwsOpExec exec_base
Definition: ops_dispatch.c:31
SwsOpExec::in_sub_y
uint8_t in_sub_y[4]
Definition: ops_dispatch.h:55
SwsOpPass::pixel_bits_in
int pixel_bits_in
Definition: ops_dispatch.c:39
SwsOpPass::tail_off_in
int tail_off_in
Definition: ops_dispatch.c:33
SwsOpPass::memcpy_out
bool memcpy_out
Definition: ops_dispatch.c:44
mem.h
SwsGraph
Filter graph, which represents a 'baked' pixel format conversion.
Definition: graph.h:103
AVPixFmtDescriptor
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:69
av_free
#define av_free(p)
Definition: tableprint_vlc.h:34
SwsSwizzleOp::in
uint8_t in[4]
Definition: ops.h:127
op_pass_run
static void op_pass_run(const SwsFrame *out, const SwsFrame *in, const int y, const int h, const SwsPass *pass)
Definition: ops_dispatch.c:252
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
h
h
Definition: vp9dsp_template.c:2070
SwsOpList
Helper struct for representing a list of operations.
Definition: ops.h:222
SwsContext
Main external API structure.
Definition: swscale.h:191
SwsOpPass::tail_off_out
int tail_off_out
Definition: ops_dispatch.c:34
SwsFrame::linesize
int linesize[4]
Definition: format.h:191
AVPixFmtDescriptor::log2_chroma_h
uint8_t log2_chroma_h
Amount to shift the luma height right to find the chroma height.
Definition: pixdesc.h:89
SwsOpExec::out_bump
ptrdiff_t out_bump[4]
Definition: ops_dispatch.h:46
read
static uint32_t BS_FUNC() read(BSCTX *bc, unsigned int n)
Return n bits from the buffer, n has to be in the 0-32 range.
Definition: bitstream_template.h:239
get_row_data
static void get_row_data(const SwsOpPass *p, const int y, const uint8_t *in[4], uint8_t *out[4])
Definition: ops_dispatch.c:108