FFmpeg
ops_backend.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 "ops_backend.h"
22 
23 #if AV_GCC_VERSION_AT_LEAST(4, 4)
24 #pragma GCC optimize ("finite-math-only")
25 #endif
26 
27 /* Array-based reference implementation */
28 
29 #ifndef SWS_BLOCK_SIZE
30 # define SWS_BLOCK_SIZE 32
31 #endif
32 
33 typedef uint8_t u8block_t[SWS_BLOCK_SIZE];
34 typedef uint16_t u16block_t[SWS_BLOCK_SIZE];
35 typedef uint32_t u32block_t[SWS_BLOCK_SIZE];
36 typedef float f32block_t[SWS_BLOCK_SIZE];
37 
38 #define BIT_DEPTH 8
39 # include "ops_tmpl_int.c"
40 #undef BIT_DEPTH
41 
42 #define BIT_DEPTH 16
43 # include "ops_tmpl_int.c"
44 #undef BIT_DEPTH
45 
46 #define BIT_DEPTH 32
47 # include "ops_tmpl_int.c"
48 # include "ops_tmpl_float.c"
49 #undef BIT_DEPTH
50 
51 static void process(const SwsOpExec *exec, const void *priv,
52  const int bx_start, const int y_start, int bx_end, int y_end)
53 {
54  const SwsOpChain *chain = priv;
55  const SwsOpImpl *impl = chain->impl;
56  SwsOpIter iter;
57 
58  for (iter.y = y_start; iter.y < y_end; iter.y++) {
59  for (int i = 0; i < 4; i++) {
60  iter.in[i] = exec->in[i] + (iter.y - y_start) * exec->in_stride[i];
61  iter.out[i] = exec->out[i] + (iter.y - y_start) * exec->out_stride[i];
62  }
63 
64  for (int block = bx_start; block < bx_end; block++) {
65  iter.x = block * SWS_BLOCK_SIZE;
66  ((void (*)(SwsOpIter *, const SwsOpImpl *)) impl->cont)
67  (&iter, &impl[1]);
68  }
69  }
70 }
71 
73 {
74  int ret;
75 
77  if (!chain)
78  return AVERROR(ENOMEM);
79 
80  static const SwsOpTable *const tables[] = {
81  &bitfn(op_table_int, u8),
82  &bitfn(op_table_int, u16),
83  &bitfn(op_table_int, u32),
84  &bitfn(op_table_float, f32),
85  };
86 
87  do {
89  SWS_BLOCK_SIZE, chain);
90  } while (ret == AVERROR(EAGAIN));
91  if (ret < 0) {
92  ff_sws_op_chain_free(chain);
93  return ret;
94  }
95 
96  *out = (SwsCompiledOp) {
97  .func = process,
98  .block_size = SWS_BLOCK_SIZE,
99  .cpu_flags = chain->cpu_flags,
100  .priv = chain,
101  .free = (void (*)(void *)) ff_sws_op_chain_free,
102  };
103  return 0;
104 }
105 
107  .name = "c",
108  .compile = compile,
109 };
SwsOpTable
Definition: ops_chain.h:118
compile
static int compile(SwsContext *ctx, SwsOpList *ops, SwsCompiledOp *out)
Definition: ops_backend.c:72
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
ops_backend.h
f32block_t
float f32block_t[SWS_BLOCK_SIZE]
Definition: ops_backend.c:36
out
FILE * out
Definition: movenc.c:55
SwsOpExec::out_stride
ptrdiff_t out_stride[4]
Definition: ops_internal.h:63
SwsOpExec::in
const uint8_t * in[4]
Definition: ops_internal.h:58
SwsOpImpl::cont
SwsFuncPtr cont
Definition: ops_chain.h:68
backend_c
const SwsOpBackend backend_c
Copyright (C) 2025 Niklas Haas.
Definition: ops_backend.c:106
SwsOpIter
Copyright (C) 2025 Niklas Haas.
Definition: ops_backend.h:46
SwsOpExec::in_stride
ptrdiff_t in_stride[4]
Definition: ops_internal.h:62
SwsOpIter::out
uint8_t * out[4]
Definition: ops_backend.h:48
SwsOpBackend::name
const char * name
Definition: ops_internal.h:104
SwsOpChain::cpu_flags
int cpu_flags
Definition: ops_chain.h:85
SwsOpIter::x
int x
Definition: ops_backend.h:49
tables
Writing a table generator This documentation is preliminary Parts of the API are not good and should be changed Basic concepts A table generator consists of two *_tablegen c and *_tablegen h The h file will provide the variable declarations and initialization code for the tables
Definition: tablegen.txt:10
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
u8block_t
uint8_t u8block_t[SWS_BLOCK_SIZE]
Definition: ops_backend.c:33
ff_sws_op_chain_alloc
SwsOpChain * ff_sws_op_chain_alloc(void)
Definition: ops_chain.c:29
u16block_t
uint16_t u16block_t[SWS_BLOCK_SIZE]
Definition: ops_backend.c:34
SwsOpImpl
Definition: ops_chain.h:67
ctx
AVFormatContext * ctx
Definition: movenc.c:49
u32block_t
uint32_t u32block_t[SWS_BLOCK_SIZE]
Definition: ops_backend.c:35
SwsOpChain::impl
SwsOpImpl impl[SWS_MAX_OPS+1]
Definition: ops_chain.h:82
bitfn
#define bitfn(name, ext)
Definition: ops_backend.h:65
SwsOpBackend
Definition: ops_internal.h:103
ops_tmpl_int.c
SWS_BLOCK_SIZE
#define SWS_BLOCK_SIZE
Copyright (C) 2025 Niklas Haas.
Definition: ops_backend.c:30
SwsOpExec
Global execution context for all compiled functions.
Definition: ops_internal.h:56
SwsOpChain
Compiled "chain" of operations, which can be dispatched efficiently.
Definition: ops_chain.h:80
ff_sws_op_compile_tables
int ff_sws_op_compile_tables(const SwsOpTable *const tables[], int num_tables, SwsOpList *ops, const int block_size, SwsOpChain *chain)
"Compile" a single op by looking it up in a list of fixed size op tables.
Definition: ops_chain.c:195
process
static void process(const SwsOpExec *exec, const void *priv, const int bx_start, const int y_start, int bx_end, int y_end)
Definition: ops_backend.c:51
ops_tmpl_float.c
SwsOpExec::out
uint8_t * out[4]
Definition: ops_internal.h:59
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
SwsOpChain::free
void(* free[SWS_MAX_OPS+1])(void *)
Definition: ops_chain.h:83
ret
ret
Definition: filter_design.txt:187
SwsCompiledOp
Definition: ops_internal.h:90
SwsOpIter::in
const uint8_t * in[4]
Definition: ops_backend.h:47
ff_sws_op_chain_free
void ff_sws_op_chain_free(SwsOpChain *chain)
Definition: ops_chain.c:34
block
The exact code depends on how similar the blocks are and how related they are to the block
Definition: filter_design.txt:207
SwsOpList
Helper struct for representing a list of operations.
Definition: ops.h:209
SwsContext
Main external API structure.
Definition: swscale.h:189
SwsOpIter::y
int y
Definition: ops_backend.h:49