FFmpeg
sws_ops.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/mem.h"
22 #include "libavutil/pixdesc.h"
23 #include "libswscale/ops.h"
27 #include "libswscale/format.h"
28 
29 #ifdef _WIN32
30 #include <io.h>
31 #include <fcntl.h>
32 #endif
33 
34 static int pass_idx;
35 
36 static int print_ops(SwsContext *ctx, const SwsOpList *ops, SwsCompiledOp *out)
37 {
39  if (!uops)
40  return AVERROR(ENOMEM);
41 
42  int ret = ff_sws_ops_translate(ctx, ops, 0, uops);
43  if (ret == AVERROR(ENOTSUP))
44  goto fail;
45 
46  if (pass_idx > 0)
47  av_log(NULL, AV_LOG_INFO, " Sub-pass #%d:\n", pass_idx);
48 
50  if (ret < 0) {
51  av_log(NULL, AV_LOG_ERROR, "Error translating ops: %s\n", av_err2str(ret));
52  goto fail;
53  }
54 
55  av_log(NULL, AV_LOG_INFO, " translated micro-ops:\n");
56  for (int i = 0; i < uops->num_ops; i++) {
57  char name[SWS_UOP_NAME_MAX];
58  ff_sws_uop_name(&uops->ops[i], name);
59  av_log(NULL, AV_LOG_INFO, " %s\n", name);
60  }
61 
62  *out = (SwsCompiledOp) {0}; /* dummy value, will be immediately freed */
63  pass_idx++;
64  ret = 0;
65 
66 fail:
67  ff_sws_uop_list_free(&uops);
68  return ret;
69 }
70 
71 /* Dummy backend that just prints all seen op lists */
72 static const SwsOpBackend backend_print = {
73  .name = "print_ops",
74  .compile = print_ops,
75 };
76 
77 static int print_passes(SwsContext *ctx, void *graph, SwsOpList *ops)
78 {
79  av_log(NULL, AV_LOG_INFO, "%s %dx%d -> %s %dx%d:\n",
81  ops->src.width, ops->src.height,
83  ops->dst.width, ops->dst.height);
84 
85  if (ff_sws_op_list_is_noop(ops)) {
86  av_log(NULL, AV_LOG_INFO, " (no-op)\n");
87  return 0;
88  }
89 
90  /* ff_sws_compile_pass() takes over ownership of `ops` */
92  if (!copy)
93  return AVERROR(ENOMEM);
94 
95  pass_idx = 0;
97  return ff_sws_compile_pass(graph, &backend_print, &copy, flags, NULL, NULL);
98 }
99 static void log_stdout(void *avcl, int level, const char *fmt, va_list vl)
100 {
101  if (level != AV_LOG_INFO) {
102  av_log_default_callback(avcl, level, fmt, vl);
103  } else if (av_log_get_level() >= AV_LOG_INFO) {
104  vfprintf(stdout, fmt, vl);
105  }
106 }
107 
108 int main(int argc, char **argv)
109 {
110  enum AVPixelFormat src_fmt = AV_PIX_FMT_NONE;
111  enum AVPixelFormat dst_fmt = AV_PIX_FMT_NONE;
112  SwsContext *ctx = NULL;
113  SwsGraph *graph = NULL;
114  int ret = 1;
115 
116 #ifdef _WIN32
117  _setmode(_fileno(stdout), _O_BINARY);
118 #endif
119 
120  for (int i = 1; i < argc; i++) {
121  if (!strcmp(argv[i], "-help") || !strcmp(argv[i], "--help")) {
122  fprintf(stderr,
123  "sws_ops [options...]\n"
124  " -help\n"
125  " This text\n"
126  " -dst <pixfmt>\n"
127  " Only test the specified destination pixel format\n"
128  " -src <pixfmt>\n"
129  " Only test the specified source pixel format\n"
130  " -v <level>\n"
131  " Enable log verbosity at given level\n"
132  );
133  return 0;
134  }
135  if (!strcmp(argv[i], "-src")) {
136  if (i + 1 >= argc)
137  goto bad_option;
138  src_fmt = av_get_pix_fmt(argv[i + 1]);
139  if (src_fmt == AV_PIX_FMT_NONE) {
140  fprintf(stderr, "invalid pixel format %s\n", argv[i + 1]);
141  return AVERROR(EINVAL);
142  }
143  i++;
144  } else if (!strcmp(argv[i], "-dst")) {
145  if (i + 1 >= argc)
146  goto bad_option;
147  dst_fmt = av_get_pix_fmt(argv[i + 1]);
148  if (dst_fmt == AV_PIX_FMT_NONE) {
149  fprintf(stderr, "invalid pixel format %s\n", argv[i + 1]);
150  return AVERROR(EINVAL);
151  }
152  i++;
153  } else if (!strcmp(argv[i], "-v")) {
154  if (i + 1 >= argc)
155  goto bad_option;
156  av_log_set_level(atoi(argv[i + 1]));
157  i++;
158  } else {
159 bad_option:
160  fprintf(stderr, "bad option or argument missing (%s) see -help\n", argv[i]);
161  return AVERROR(EINVAL);
162  }
163  }
164 
165  /* Allocate dummy graph and context for ff_sws_compile_pass() */
166  graph = ff_sws_graph_alloc();
167  if (!graph)
168  goto fail;
169  graph->ctx = ctx = sws_alloc_context();
170  if (!ctx)
171  goto fail;
172  ctx->scaler = SWS_SCALE_BILINEAR; /* reduce filter generation overhead */
173 
175 
176  ret = ff_sws_enum_op_lists(ctx, graph, src_fmt, dst_fmt, print_passes);
177  if (ret < 0)
178  goto fail;
179 
180  ret = 0;
181 fail:
183  ff_sws_graph_free(&graph);
184  return ret;
185 }
flags
const SwsFlags flags[]
Definition: swscale.c:85
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:71
name
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default minimum maximum flags name is the option name
Definition: writing_filters.txt:88
level
uint8_t level
Definition: svq3.c:208
SwsGraph::ctx
SwsContext * ctx
Definition: graph.h:123
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
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:663
out
static FILE * out
Definition: movenc.c:55
pass_idx
static int pass_idx
Definition: sws_ops.c:34
SWS_SCALE_BILINEAR
@ SWS_SCALE_BILINEAR
bilinear filtering
Definition: swscale.h:98
main
int main(int argc, char **argv)
Definition: sws_ops.c:108
pixdesc.h
ops.h
ops_dispatch.h
format.h
SwsOpBackend::name
const char * name
Definition: ops_dispatch.h:134
SWS_UOP_NAME_MAX
#define SWS_UOP_NAME_MAX
Generate a unique name for a SwsUOp.
Definition: uops.h:252
ff_sws_graph_alloc
SwsGraph * ff_sws_graph_alloc(void)
Allocate an empty SwsGraph.
Definition: graph.c:817
print_ops
static int print_ops(SwsContext *ctx, const SwsOpList *ops, SwsCompiledOp *out)
Definition: sws_ops.c:36
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:960
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:210
SwsFormat::height
int height
Definition: format.h:78
ff_sws_enum_op_lists
static int ff_sws_enum_op_lists(SwsContext *ctx, void *opaque, enum AVPixelFormat src_fmt, enum AVPixelFormat dst_fmt, int(*cb)(SwsContext *ctx, void *opaque, SwsOpList *ops))
Helper function to enumerate over all possible (optimized) operation lists, under the current set of ...
Definition: op_list_gen_template.c:89
ctx
static AVFormatContext * ctx
Definition: movenc.c:49
SwsOpBackend
Definition: ops_dispatch.h:133
av_log_get_level
int av_log_get_level(void)
Get the current log level.
Definition: log.c:472
fail
#define fail
Definition: test.h:478
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:748
NULL
#define NULL
Definition: coverity.c:32
ff_sws_graph_free
void ff_sws_graph_free(SwsGraph **pgraph)
Uninitialize any state associate with this filter graph and free it.
Definition: graph.c:890
av_log_set_callback
void av_log_set_callback(void(*callback)(void *, int, const char *, va_list))
Set the logging callback.
Definition: log.c:492
copy
static void copy(const float *p1, float *p2, const int length)
Definition: vf_vaguedenoiser.c:186
SWS_OP_FLAG_SPLIT_MEMCPY
@ SWS_OP_FLAG_SPLIT_MEMCPY
Definition: ops_dispatch.h:173
sws_alloc_context
SwsContext * sws_alloc_context(void)
Allocate an empty SwsContext and set its fields to default values.
Definition: utils.c:1043
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
SwsOpList::src
SwsFormat src
Definition: ops.h:270
log_stdout
static void log_stdout(void *avcl, int level, const char *fmt, va_list vl)
Definition: sws_ops.c:99
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:221
ff_sws_uop_list_alloc
SwsUOpList * ff_sws_uop_list_alloc(void)
Definition: uops.c:204
av_log_set_level
void av_log_set_level(int level)
Set the log level.
Definition: log.c:477
SwsFormat::format
enum AVPixelFormat format
Definition: format.h:81
ops_internal.h
SwsFormat::width
int width
Definition: format.h:78
backend_print
static const SwsOpBackend backend_print
Definition: sws_ops.c:72
op_list_gen_template.c
ff_sws_ops_translate
int ff_sws_ops_translate(SwsContext *ctx, const SwsOpList *ops, SwsUOpFlags flags, SwsUOpList *uops)
Translate a list of operations down to micro-ops, which can be further optimized and then directly ex...
Definition: uops.c:685
ret
ret
Definition: filter_design.txt:187
SwsUOpList::num_ops
int num_ops
Definition: uops.h:257
SwsOpList::dst
SwsFormat dst
Definition: ops.h:270
SwsCompiledOp
Definition: ops_dispatch.h:100
ff_sws_uop_list_free
void ff_sws_uop_list_free(SwsUOpList **p_ops)
Definition: uops.c:190
av_get_pix_fmt
enum AVPixelFormat av_get_pix_fmt(const char *name)
Return the pixel format corresponding to name.
Definition: pixdesc.c:3388
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:72
ff_sws_uop_name
void ff_sws_uop_name(const SwsUOp *op, char buf[SWS_UOP_NAME_MAX])
Definition: uops.c:81
SwsUOpList
Definition: uops.h:255
ff_sws_compile_pass
int ff_sws_compile_pass(SwsGraph *graph, const SwsOpBackend *backend, SwsOpList **pops, int flags, SwsPass *input, SwsPass **output)
Resolves an operation list to a graph pass.
Definition: ops_dispatch.c:751
av_log_default_callback
void av_log_default_callback(void *ptr, int level, const char *fmt, va_list vl)
Default logging callback.
Definition: log.c:380
mem.h
SwsGraph
Filter graph, which represents a 'baked' pixel format conversion.
Definition: graph.h:122
sws_free_context
void sws_free_context(SwsContext **ctx)
Free the context and everything associated with it, and write NULL to the provided pointer.
Definition: utils.c:2381
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
print_passes
static int print_passes(SwsContext *ctx, void *graph, SwsOpList *ops)
Definition: sws_ops.c:77
SwsOpList
Helper struct for representing a list of operations.
Definition: ops.h:265
SwsContext
Main external API structure.
Definition: swscale.h:229
SWS_OP_FLAG_DRY_RUN
@ SWS_OP_FLAG_DRY_RUN
Definition: ops_dispatch.h:170
SwsUOpList::ops
SwsUOp * ops
Definition: uops.h:256
av_get_pix_fmt_name
const char * av_get_pix_fmt_name(enum AVPixelFormat pix_fmt)
Return the short name for a pixel format, NULL in case pix_fmt is unknown.
Definition: pixdesc.c:3376