FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/fftools/opt_common.c
Date: 2026-08-26 10:34:04
Exec Total Coverage
Lines: 131 779 16.8%
Functions: 10 53 18.9%
Branches: 110 643 17.1%

Line Branch Exec Source
1 /*
2 * Option handlers shared between the tools.
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 "config.h"
22
23 #include <stdio.h>
24
25 #include "cmdutils.h"
26 #include "fopen_utf8.h"
27 #include "opt_common.h"
28
29 #include "libavutil/avassert.h"
30 #include "libavutil/avstring.h"
31 #include "libavutil/bprint.h"
32 #include "libavutil/channel_layout.h"
33 #include "libavutil/cpu.h"
34 #include "libavutil/dict.h"
35 #include "libavutil/error.h"
36 #include "libavutil/ffversion.h"
37 #include "libavutil/log.h"
38 #include "libavutil/mem.h"
39 #include "libavutil/parseutils.h"
40 #include "libavutil/pixdesc.h"
41 #include "libavutil/version.h"
42
43 #include "libavcodec/avcodec.h"
44 #include "libavcodec/bsf.h"
45 #include "libavcodec/codec.h"
46 #include "libavcodec/codec_desc.h"
47 #include "libavcodec/version.h"
48
49 #include "libavformat/avformat.h"
50 #include "libavformat/version.h"
51
52 #include "libavdevice/avdevice.h"
53 #include "libavdevice/version.h"
54
55 #include "libavfilter/avfilter.h"
56 #include "libavfilter/version.h"
57
58 #include "libswscale/swscale.h"
59 #include "libswscale/version.h"
60
61 #include "libswresample/swresample.h"
62 #include "libswresample/version.h"
63
64
65 enum show_muxdemuxers {
66 SHOW_DEFAULT,
67 SHOW_DEMUXERS,
68 SHOW_MUXERS,
69 };
70
71 enum show_codec {
72 SHOW_DECODER,
73 SHOW_ENCODER,
74 };
75
76 static FILE *report_file;
77 static int report_file_level = AV_LOG_DEBUG;
78
79 int show_license(void *optctx, const char *opt, const char *arg)
80 {
81 #if CONFIG_NONFREE
82 printf(
83 "This version of %s has nonfree parts compiled in.\n"
84 "Therefore it is not legally redistributable.\n",
85 program_name );
86 #elif CONFIG_GPLV3
87 printf(
88 "%s is free software; you can redistribute it and/or modify\n"
89 "it under the terms of the GNU General Public License as published by\n"
90 "the Free Software Foundation; either version 3 of the License, or\n"
91 "(at your option) any later version.\n"
92 "\n"
93 "%s is distributed in the hope that it will be useful,\n"
94 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
95 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
96 "GNU General Public License for more details.\n"
97 "\n"
98 "You should have received a copy of the GNU General Public License\n"
99 "along with %s. If not, see <http://www.gnu.org/licenses/>.\n",
100 program_name, program_name, program_name );
101 #elif CONFIG_GPL
102 printf(
103 "%s is free software; you can redistribute it and/or modify\n"
104 "it under the terms of the GNU General Public License as published by\n"
105 "the Free Software Foundation; either version 2 of the License, or\n"
106 "(at your option) any later version.\n"
107 "\n"
108 "%s is distributed in the hope that it will be useful,\n"
109 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
110 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
111 "GNU General Public License for more details.\n"
112 "\n"
113 "You should have received a copy of the GNU General Public License\n"
114 "along with %s; if not, write to the Free Software\n"
115 "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n",
116 program_name, program_name, program_name );
117 #elif CONFIG_LGPLV3
118 printf(
119 "%s is free software; you can redistribute it and/or modify\n"
120 "it under the terms of the GNU Lesser General Public License as published by\n"
121 "the Free Software Foundation; either version 3 of the License, or\n"
122 "(at your option) any later version.\n"
123 "\n"
124 "%s is distributed in the hope that it will be useful,\n"
125 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
126 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
127 "GNU Lesser General Public License for more details.\n"
128 "\n"
129 "You should have received a copy of the GNU Lesser General Public License\n"
130 "along with %s. If not, see <http://www.gnu.org/licenses/>.\n",
131 program_name, program_name, program_name );
132 #else
133 printf(
134 "%s is free software; you can redistribute it and/or\n"
135 "modify it under the terms of the GNU Lesser General Public\n"
136 "License as published by the Free Software Foundation; either\n"
137 "version 2.1 of the License, or (at your option) any later version.\n"
138 "\n"
139 "%s is distributed in the hope that it will be useful,\n"
140 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
141 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n"
142 "Lesser General Public License for more details.\n"
143 "\n"
144 "You should have received a copy of the GNU Lesser General Public\n"
145 "License along with %s; if not, write to the Free Software\n"
146 "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n",
147 program_name, program_name, program_name );
148 #endif
149
150 return 0;
151 }
152
153 static int warned_cfg = 0;
154
155 #define INDENT 1
156 #define SHOW_VERSION 2
157 #define SHOW_CONFIG 4
158 #define SHOW_COPYRIGHT 8
159
160 #define PRINT_LIB_INFO(libname, LIBNAME, flags, level) \
161 if (CONFIG_##LIBNAME) { \
162 const char *indent = flags & INDENT? " " : ""; \
163 if (flags & SHOW_VERSION) { \
164 unsigned int version = libname##_version(); \
165 av_log(NULL, level, \
166 "%slib%-11s %2d.%3d.%3d / %2d.%3d.%3d\n", \
167 indent, #libname, \
168 LIB##LIBNAME##_VERSION_MAJOR, \
169 LIB##LIBNAME##_VERSION_MINOR, \
170 LIB##LIBNAME##_VERSION_MICRO, \
171 AV_VERSION_MAJOR(version), AV_VERSION_MINOR(version),\
172 AV_VERSION_MICRO(version)); \
173 } \
174 if (flags & SHOW_CONFIG) { \
175 const char *cfg = libname##_configuration(); \
176 if (strcmp(FFMPEG_CONFIGURATION, cfg)) { \
177 if (!warned_cfg) { \
178 av_log(NULL, level, \
179 "%sWARNING: library configuration mismatch\n", \
180 indent); \
181 warned_cfg = 1; \
182 } \
183 av_log(NULL, level, "%s%-11s configuration: %s\n", \
184 indent, #libname, cfg); \
185 } \
186 } \
187 } \
188
189 17948 static void print_all_libs_info(int flags, int level)
190 {
191
6/10
✓ Branch 0 taken 17948 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8974 times.
✓ Branch 3 taken 8974 times.
✓ Branch 6 taken 8974 times.
✓ Branch 7 taken 8974 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 8974 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
17948 PRINT_LIB_INFO(avutil, AVUTIL, flags, level);
192
6/10
✓ Branch 0 taken 17948 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8974 times.
✓ Branch 3 taken 8974 times.
✓ Branch 6 taken 8974 times.
✓ Branch 7 taken 8974 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 8974 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
17948 PRINT_LIB_INFO(avcodec, AVCODEC, flags, level);
193
6/10
✓ Branch 0 taken 17948 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8974 times.
✓ Branch 3 taken 8974 times.
✓ Branch 6 taken 8974 times.
✓ Branch 7 taken 8974 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 8974 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
17948 PRINT_LIB_INFO(avformat, AVFORMAT, flags, level);
194
6/10
✓ Branch 0 taken 17948 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8974 times.
✓ Branch 3 taken 8974 times.
✓ Branch 6 taken 8974 times.
✓ Branch 7 taken 8974 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 8974 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
17948 PRINT_LIB_INFO(avdevice, AVDEVICE, flags, level);
195
6/10
✓ Branch 0 taken 17948 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8974 times.
✓ Branch 3 taken 8974 times.
✓ Branch 6 taken 8974 times.
✓ Branch 7 taken 8974 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 8974 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
17948 PRINT_LIB_INFO(avfilter, AVFILTER, flags, level);
196
6/10
✓ Branch 0 taken 17948 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8974 times.
✓ Branch 3 taken 8974 times.
✓ Branch 6 taken 8974 times.
✓ Branch 7 taken 8974 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 8974 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
17948 PRINT_LIB_INFO(swscale, SWSCALE, flags, level);
197
6/10
✓ Branch 0 taken 17948 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8974 times.
✓ Branch 3 taken 8974 times.
✓ Branch 6 taken 8974 times.
✓ Branch 7 taken 8974 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 8974 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
17948 PRINT_LIB_INFO(swresample, SWRESAMPLE, flags, level);
198 17948 }
199
200 8974 static void print_program_info(int flags, int level)
201 {
202
1/2
✓ Branch 0 taken 8974 times.
✗ Branch 1 not taken.
8974 const char *indent = flags & INDENT? " " : "";
203
204 8974 av_log(NULL, level, "%s version %s", program_name, FFMPEG_VERSION);
205
1/2
✓ Branch 0 taken 8974 times.
✗ Branch 1 not taken.
8974 if (flags & SHOW_COPYRIGHT)
206 8974 av_log(NULL, level, " Copyright (c) %d-%d the FFmpeg developers",
207 program_birth_year, CONFIG_THIS_YEAR);
208 8974 av_log(NULL, level, "\n");
209 8974 av_log(NULL, level, "%sbuilt with %s\n", indent, CC_IDENT);
210
211 8974 av_log(NULL, level, "%sconfiguration: %s\n", indent, FFMPEG_CONFIGURATION);
212 8974 }
213
214 static void print_buildconf(int flags, int level)
215 {
216 const char *indent = flags & INDENT ? " " : "";
217 char str[] = { FFMPEG_CONFIGURATION };
218 char *conflist, *remove_tilde, *splitconf;
219
220 // Change all the ' --' strings to '~--' so that
221 // they can be identified as tokens.
222 while ((conflist = strstr(str, " --")) != NULL) {
223 conflist[0] = '~';
224 }
225
226 // Compensate for the weirdness this would cause
227 // when passing 'pkg-config --static'.
228 while ((remove_tilde = strstr(str, "pkg-config~")) != NULL) {
229 remove_tilde[sizeof("pkg-config~") - 2] = ' ';
230 }
231
232 splitconf = strtok(str, "~");
233 av_log(NULL, level, "\n%sconfiguration:\n", indent);
234 while (splitconf != NULL) {
235 av_log(NULL, level, "%s%s%s\n", indent, indent, splitconf);
236 splitconf = strtok(NULL, "~");
237 }
238 }
239
240 9007 void show_banner(int argc, char **argv, const OptionDef *options)
241 {
242 9007 int idx = locate_option(argc, argv, options, "version");
243
3/4
✓ Branch 0 taken 8974 times.
✓ Branch 1 taken 33 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 8974 times.
9007 if (hide_banner || idx)
244 33 return;
245
246 8974 print_program_info (INDENT|SHOW_COPYRIGHT, AV_LOG_INFO);
247 8974 print_all_libs_info(INDENT|SHOW_CONFIG, AV_LOG_INFO);
248 8974 print_all_libs_info(INDENT|SHOW_VERSION, AV_LOG_INFO);
249 }
250
251 int show_version(void *optctx, const char *opt, const char *arg)
252 {
253 av_log_set_callback(log_callback_help);
254 print_program_info (SHOW_COPYRIGHT, AV_LOG_INFO);
255 print_all_libs_info(SHOW_VERSION, AV_LOG_INFO);
256
257 return 0;
258 }
259
260 int show_buildconf(void *optctx, const char *opt, const char *arg)
261 {
262 av_log_set_callback(log_callback_help);
263 print_buildconf (INDENT|0, AV_LOG_INFO);
264
265 return 0;
266 }
267
268 #define PRINT_CODEC_SUPPORTED(codec, config, type, name, elem, fmt, ...) \
269 do { \
270 int num = 0; \
271 const type *elem = NULL; \
272 avcodec_get_supported_config(NULL, codec, config, 0, \
273 (const void **) &elem, &num); \
274 if (elem) { \
275 printf(" Supported " name ":"); \
276 for (int i = 0; i < num; i++) { \
277 printf(" " fmt, __VA_ARGS__); \
278 elem++; \
279 } \
280 printf("\n"); \
281 } \
282 } while (0)
283
284 static const char *get_channel_layout_desc(const AVChannelLayout *layout, AVBPrint *bp)
285 {
286 int ret;
287 av_bprint_clear(bp);
288 ret = av_channel_layout_describe_bprint(layout, bp);
289 if (!av_bprint_is_complete(bp) || ret < 0)
290 return "unknown/invalid";
291 return bp->str;
292 }
293
294 static void print_codec(const AVCodec *c)
295 {
296 int encoder = av_codec_is_encoder(c);
297 AVBPrint desc;
298
299 printf("%s %s [%s]:\n", encoder ? "Encoder" : "Decoder", c->name,
300 c->long_name ? c->long_name : "");
301
302 printf(" General capabilities: ");
303 if (c->capabilities & AV_CODEC_CAP_DRAW_HORIZ_BAND)
304 printf("horizband ");
305 if (c->capabilities & AV_CODEC_CAP_DR1)
306 printf("dr1 ");
307 if (c->capabilities & AV_CODEC_CAP_DELAY)
308 printf("delay ");
309 if (c->capabilities & AV_CODEC_CAP_SMALL_LAST_FRAME)
310 printf("small ");
311 if (c->capabilities & AV_CODEC_CAP_EXPERIMENTAL)
312 printf("exp ");
313 if (c->capabilities & AV_CODEC_CAP_CHANNEL_CONF)
314 printf("chconf ");
315 if (c->capabilities & AV_CODEC_CAP_PARAM_CHANGE)
316 printf("paramchange ");
317 if (c->capabilities & AV_CODEC_CAP_VARIABLE_FRAME_SIZE)
318 printf("variable ");
319 if (c->capabilities & (AV_CODEC_CAP_FRAME_THREADS |
320 AV_CODEC_CAP_SLICE_THREADS |
321 AV_CODEC_CAP_OTHER_THREADS))
322 printf("threads ");
323 if (c->capabilities & AV_CODEC_CAP_AVOID_PROBING)
324 printf("avoidprobe ");
325 if (c->capabilities & AV_CODEC_CAP_HARDWARE)
326 printf("hardware ");
327 if (c->capabilities & AV_CODEC_CAP_HYBRID)
328 printf("hybrid ");
329 if (c->capabilities & AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE)
330 printf("reorderedopaque ");
331 if (c->capabilities & AV_CODEC_CAP_ENCODER_FLUSH)
332 printf("flush ");
333 if (c->capabilities & AV_CODEC_CAP_ENCODER_RECON_FRAME)
334 printf("reconframe ");
335 if (!c->capabilities)
336 printf("none");
337 printf("\n");
338
339 if (c->type == AVMEDIA_TYPE_VIDEO ||
340 c->type == AVMEDIA_TYPE_AUDIO) {
341 printf(" Threading capabilities: ");
342 switch (c->capabilities & (AV_CODEC_CAP_FRAME_THREADS |
343 AV_CODEC_CAP_SLICE_THREADS |
344 AV_CODEC_CAP_OTHER_THREADS)) {
345 case AV_CODEC_CAP_FRAME_THREADS |
346 AV_CODEC_CAP_SLICE_THREADS: printf("frame and slice"); break;
347 case AV_CODEC_CAP_FRAME_THREADS: printf("frame"); break;
348 case AV_CODEC_CAP_SLICE_THREADS: printf("slice"); break;
349 case AV_CODEC_CAP_OTHER_THREADS: printf("other"); break;
350 default: printf("none"); break;
351 }
352 printf("\n");
353 }
354
355 if (avcodec_get_hw_config(c, 0)) {
356 printf(" Supported hardware devices: ");
357 for (int i = 0;; i++) {
358 const AVCodecHWConfig *config = avcodec_get_hw_config(c, i);
359 const char *name;
360 if (!config)
361 break;
362 name = av_hwdevice_get_type_name(config->device_type);
363 if (name)
364 printf("%s ", name);
365 }
366 printf("\n");
367 }
368
369 PRINT_CODEC_SUPPORTED(c, AV_CODEC_CONFIG_FRAME_RATE, AVRational, "framerates",
370 fps, "%d/%d", fps->num, fps->den);
371 PRINT_CODEC_SUPPORTED(c, AV_CODEC_CONFIG_PIX_FORMAT, enum AVPixelFormat,
372 "pixel formats", fmt, "%s", av_get_pix_fmt_name(*fmt));
373 PRINT_CODEC_SUPPORTED(c, AV_CODEC_CONFIG_SAMPLE_RATE, int, "sample rates",
374 rate, "%d", *rate);
375 PRINT_CODEC_SUPPORTED(c, AV_CODEC_CONFIG_SAMPLE_FORMAT, enum AVSampleFormat,
376 "sample formats", fmt, "%s", av_get_sample_fmt_name(*fmt));
377
378 av_bprint_init(&desc, 0, AV_BPRINT_SIZE_AUTOMATIC);
379 PRINT_CODEC_SUPPORTED(c, AV_CODEC_CONFIG_CHANNEL_LAYOUT, AVChannelLayout,
380 "channel layouts", layout, "%s",
381 get_channel_layout_desc(layout, &desc));
382 av_bprint_finalize(&desc, NULL);
383
384 if (c->priv_class) {
385 show_help_children(c->priv_class,
386 AV_OPT_FLAG_ENCODING_PARAM |
387 AV_OPT_FLAG_DECODING_PARAM);
388 }
389 }
390
391 static const AVCodec *next_codec_for_id(enum AVCodecID id, void **iter,
392 int encoder)
393 {
394 const AVCodec *c;
395 while ((c = av_codec_iterate(iter))) {
396 if (c->id == id &&
397 (encoder ? av_codec_is_encoder(c) : av_codec_is_decoder(c)))
398 return c;
399 }
400 return NULL;
401 }
402
403 static void show_help_codec(const char *name, int encoder)
404 {
405 const AVCodecDescriptor *desc;
406 const AVCodec *codec;
407
408 if (!name) {
409 av_log(NULL, AV_LOG_ERROR, "No codec name specified.\n");
410 return;
411 }
412
413 codec = encoder ? avcodec_find_encoder_by_name(name) :
414 avcodec_find_decoder_by_name(name);
415
416 if (codec)
417 print_codec(codec);
418 else if ((desc = avcodec_descriptor_get_by_name(name))) {
419 void *iter = NULL;
420 int printed = 0;
421
422 while ((codec = next_codec_for_id(desc->id, &iter, encoder))) {
423 printed = 1;
424 print_codec(codec);
425 }
426
427 if (!printed) {
428 av_log(NULL, AV_LOG_ERROR, "Codec '%s' is known to FFmpeg, "
429 "but no %s for it are available. FFmpeg might need to be "
430 "recompiled with additional external libraries.\n",
431 name, encoder ? "encoders" : "decoders");
432 }
433 } else {
434 av_log(NULL, AV_LOG_ERROR, "Codec '%s' is not recognized by FFmpeg.\n",
435 name);
436 }
437 }
438
439 static void show_help_demuxer(const char *name)
440 {
441 const AVInputFormat *fmt = av_find_input_format(name);
442
443 if (!fmt) {
444 av_log(NULL, AV_LOG_ERROR, "Unknown format '%s'.\n", name);
445 return;
446 }
447
448 printf("Demuxer %s [%s]:\n", fmt->name, fmt->long_name);
449
450 if (fmt->extensions)
451 printf(" Common extensions: %s.\n", fmt->extensions);
452
453 if (fmt->priv_class)
454 show_help_children(fmt->priv_class, AV_OPT_FLAG_DECODING_PARAM);
455 }
456
457 static void show_help_protocol(const char *name)
458 {
459 const AVClass *proto_class;
460
461 if (!name) {
462 av_log(NULL, AV_LOG_ERROR, "No protocol name specified.\n");
463 return;
464 }
465
466 proto_class = avio_protocol_get_class(name);
467 if (!proto_class) {
468 av_log(NULL, AV_LOG_ERROR, "Unknown protocol '%s'.\n", name);
469 return;
470 }
471
472 show_help_children(proto_class, AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_ENCODING_PARAM);
473 }
474
475 static void show_help_muxer(const char *name)
476 {
477 const AVCodecDescriptor *desc;
478 const AVOutputFormat *fmt = av_guess_format(name, NULL, NULL);
479
480 if (!fmt) {
481 av_log(NULL, AV_LOG_ERROR, "Unknown format '%s'.\n", name);
482 return;
483 }
484
485 printf("Muxer %s [%s]:\n", fmt->name, fmt->long_name);
486
487 if (fmt->extensions)
488 printf(" Common extensions: %s.\n", fmt->extensions);
489 if (fmt->mime_type)
490 printf(" Mime type: %s.\n", fmt->mime_type);
491 if (fmt->video_codec != AV_CODEC_ID_NONE &&
492 (desc = avcodec_descriptor_get(fmt->video_codec))) {
493 printf(" Default video codec: %s.\n", desc->name);
494 }
495 if (fmt->audio_codec != AV_CODEC_ID_NONE &&
496 (desc = avcodec_descriptor_get(fmt->audio_codec))) {
497 printf(" Default audio codec: %s.\n", desc->name);
498 }
499 if (fmt->subtitle_codec != AV_CODEC_ID_NONE &&
500 (desc = avcodec_descriptor_get(fmt->subtitle_codec))) {
501 printf(" Default subtitle codec: %s.\n", desc->name);
502 }
503
504 if (fmt->priv_class)
505 show_help_children(fmt->priv_class, AV_OPT_FLAG_ENCODING_PARAM);
506 }
507
508 #if CONFIG_AVFILTER
509 static void show_help_filter(const char *name)
510 {
511 #if CONFIG_AVFILTER
512 const AVFilter *f = avfilter_get_by_name(name);
513 int i, count;
514
515 if (!name) {
516 av_log(NULL, AV_LOG_ERROR, "No filter name specified.\n");
517 return;
518 } else if (!f) {
519 av_log(NULL, AV_LOG_ERROR, "Unknown filter '%s'.\n", name);
520 return;
521 }
522
523 printf("Filter %s\n", f->name);
524 if (f->description)
525 printf(" %s\n", f->description);
526
527 if (f->flags & AVFILTER_FLAG_SLICE_THREADS)
528 printf(" slice threading supported\n");
529
530 printf(" Inputs:\n");
531 count = avfilter_filter_pad_count(f, 0);
532 for (i = 0; i < count; i++) {
533 printf(" #%d: %s (%s)\n", i, avfilter_pad_get_name(f->inputs, i),
534 av_get_media_type_string(avfilter_pad_get_type(f->inputs, i)));
535 }
536 if (f->flags & AVFILTER_FLAG_DYNAMIC_INPUTS)
537 printf(" dynamic (depending on the options)\n");
538 else if (!count)
539 printf(" none (source filter)\n");
540
541 printf(" Outputs:\n");
542 count = avfilter_filter_pad_count(f, 1);
543 for (i = 0; i < count; i++) {
544 printf(" #%d: %s (%s)\n", i, avfilter_pad_get_name(f->outputs, i),
545 av_get_media_type_string(avfilter_pad_get_type(f->outputs, i)));
546 }
547 if (f->flags & AVFILTER_FLAG_DYNAMIC_OUTPUTS)
548 printf(" dynamic (depending on the options)\n");
549 else if (!count)
550 printf(" none (sink filter)\n");
551
552 if (f->priv_class)
553 show_help_children(f->priv_class, AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_FILTERING_PARAM |
554 AV_OPT_FLAG_AUDIO_PARAM);
555 if (f->flags & AVFILTER_FLAG_SUPPORT_TIMELINE)
556 printf("This filter has support for timeline through the 'enable' option.\n");
557 #else
558 av_log(NULL, AV_LOG_ERROR, "Build without libavfilter; "
559 "can not to satisfy request\n");
560 #endif
561 }
562 #endif
563
564 static void show_help_bsf(const char *name)
565 {
566 const AVBitStreamFilter *bsf = av_bsf_get_by_name(name);
567
568 if (!name) {
569 av_log(NULL, AV_LOG_ERROR, "No bitstream filter name specified.\n");
570 return;
571 } else if (!bsf) {
572 av_log(NULL, AV_LOG_ERROR, "Unknown bit stream filter '%s'.\n", name);
573 return;
574 }
575
576 printf("Bit stream filter %s\n", bsf->name);
577 if (bsf->codec_ids) {
578 const enum AVCodecID *id = bsf->codec_ids;
579 printf(" Supported codecs:");
580 while (*id != AV_CODEC_ID_NONE) {
581 printf(" %s", avcodec_descriptor_get(*id)->name);
582 id++;
583 }
584 printf("\n");
585 }
586 if (bsf->priv_class)
587 show_help_children(bsf->priv_class, AV_OPT_FLAG_BSF_PARAM);
588 }
589
590 int show_help(void *optctx, const char *opt, const char *arg)
591 {
592 char *topic, *par;
593 av_log_set_callback(log_callback_help);
594
595 topic = av_strdup(arg ? arg : "");
596 if (!topic)
597 return AVERROR(ENOMEM);
598 par = strchr(topic, '=');
599 if (par)
600 *par++ = 0;
601
602 if (!*topic) {
603 show_help_default(topic, par);
604 } else if (!strcmp(topic, "decoder")) {
605 show_help_codec(par, SHOW_DECODER);
606 } else if (!strcmp(topic, "encoder")) {
607 show_help_codec(par, SHOW_ENCODER);
608 } else if (!strcmp(topic, "demuxer")) {
609 show_help_demuxer(par);
610 } else if (!strcmp(topic, "muxer")) {
611 show_help_muxer(par);
612 } else if (!strcmp(topic, "protocol")) {
613 show_help_protocol(par);
614 #if CONFIG_AVFILTER
615 } else if (!strcmp(topic, "filter")) {
616 show_help_filter(par);
617 #endif
618 } else if (!strcmp(topic, "bsf")) {
619 show_help_bsf(par);
620 } else {
621 show_help_default(topic, par);
622 }
623
624 av_freep(&topic);
625 return 0;
626 }
627
628 static void print_codecs_for_id(enum AVCodecID id, int encoder)
629 {
630 void *iter = NULL;
631 const AVCodec *codec;
632
633 printf(" (%s:", encoder ? "encoders" : "decoders");
634
635 while ((codec = next_codec_for_id(id, &iter, encoder)))
636 printf(" %s", codec->name);
637
638 printf(")");
639 }
640
641 static int compare_codec_desc(const void *a, const void *b)
642 {
643 const AVCodecDescriptor * const *da = a;
644 const AVCodecDescriptor * const *db = b;
645
646 return (*da)->type != (*db)->type ? FFDIFFSIGN((*da)->type, (*db)->type) :
647 strcmp((*da)->name, (*db)->name);
648 }
649
650 static int get_codecs_sorted(const AVCodecDescriptor ***rcodecs)
651 {
652 const AVCodecDescriptor *desc = NULL;
653 const AVCodecDescriptor **codecs;
654 unsigned nb_codecs = 0, i = 0;
655
656 while ((desc = avcodec_descriptor_next(desc)))
657 nb_codecs++;
658 if (!(codecs = av_calloc(nb_codecs, sizeof(*codecs))))
659 return AVERROR(ENOMEM);
660 desc = NULL;
661 while ((desc = avcodec_descriptor_next(desc)))
662 codecs[i++] = desc;
663 av_assert0(i == nb_codecs);
664 qsort(codecs, nb_codecs, sizeof(*codecs), compare_codec_desc);
665 *rcodecs = codecs;
666 return nb_codecs;
667 }
668
669 static char get_media_type_char(enum AVMediaType type)
670 {
671 switch (type) {
672 case AVMEDIA_TYPE_VIDEO: return 'V';
673 case AVMEDIA_TYPE_AUDIO: return 'A';
674 case AVMEDIA_TYPE_DATA: return 'D';
675 case AVMEDIA_TYPE_SUBTITLE: return 'S';
676 case AVMEDIA_TYPE_ATTACHMENT:return 'T';
677 default: return '?';
678 }
679 }
680
681 int show_codecs(void *optctx, const char *opt, const char *arg)
682 {
683 const AVCodecDescriptor **codecs;
684 unsigned i;
685 int nb_codecs = get_codecs_sorted(&codecs);
686
687 if (nb_codecs < 0)
688 return nb_codecs;
689
690 printf("Codecs:\n"
691 " D..... = Decoding supported\n"
692 " .E.... = Encoding supported\n"
693 " ..V... = Video codec\n"
694 " ..A... = Audio codec\n"
695 " ..S... = Subtitle codec\n"
696 " ..D... = Data codec\n"
697 " ..T... = Attachment codec\n"
698 " ...I.. = Intra frame-only codec\n"
699 " ....L. = Lossy compression\n"
700 " .....S = Lossless compression\n"
701 " -------\n");
702 for (i = 0; i < nb_codecs; i++) {
703 const AVCodecDescriptor *desc = codecs[i];
704 const AVCodec *codec;
705 void *iter = NULL;
706
707 if (strstr(desc->name, "_deprecated"))
708 continue;
709
710 printf(" %c%c%c%c%c%c",
711 avcodec_find_decoder(desc->id) ? 'D' : '.',
712 avcodec_find_encoder(desc->id) ? 'E' : '.',
713 get_media_type_char(desc->type),
714 (desc->props & AV_CODEC_PROP_INTRA_ONLY) ? 'I' : '.',
715 (desc->props & AV_CODEC_PROP_LOSSY) ? 'L' : '.',
716 (desc->props & AV_CODEC_PROP_LOSSLESS) ? 'S' : '.');
717
718 printf(" %-20s %s", desc->name, desc->long_name ? desc->long_name : "");
719
720 /* print decoders/encoders when there's more than one or their
721 * names are different from codec name */
722 while ((codec = next_codec_for_id(desc->id, &iter, SHOW_DECODER))) {
723 if (strcmp(codec->name, desc->name)) {
724 print_codecs_for_id(desc->id, SHOW_DECODER);
725 break;
726 }
727 }
728 iter = NULL;
729 while ((codec = next_codec_for_id(desc->id, &iter, SHOW_ENCODER))) {
730 if (strcmp(codec->name, desc->name)) {
731 print_codecs_for_id(desc->id, SHOW_ENCODER);
732 break;
733 }
734 }
735
736 printf("\n");
737 }
738 av_free(codecs);
739 return 0;
740 }
741
742 static int print_codecs(int encoder)
743 {
744 const AVCodecDescriptor **codecs;
745 int i, nb_codecs = get_codecs_sorted(&codecs);
746
747 if (nb_codecs < 0)
748 return nb_codecs;
749
750 printf("%s:\n"
751 " V..... = Video\n"
752 " A..... = Audio\n"
753 " S..... = Subtitle\n"
754 " .F.... = Frame-level multithreading\n"
755 " ..S... = Slice-level multithreading\n"
756 " ...X.. = Codec is experimental\n"
757 " ....B. = Supports draw_horiz_band\n"
758 " .....D = Supports direct rendering method 1\n"
759 " ------\n",
760 encoder ? "Encoders" : "Decoders");
761 for (i = 0; i < nb_codecs; i++) {
762 const AVCodecDescriptor *desc = codecs[i];
763 const AVCodec *codec;
764 void *iter = NULL;
765
766 while ((codec = next_codec_for_id(desc->id, &iter, encoder))) {
767 printf(" %c%c%c%c%c%c",
768 get_media_type_char(desc->type),
769 (codec->capabilities & AV_CODEC_CAP_FRAME_THREADS) ? 'F' : '.',
770 (codec->capabilities & AV_CODEC_CAP_SLICE_THREADS) ? 'S' : '.',
771 (codec->capabilities & AV_CODEC_CAP_EXPERIMENTAL) ? 'X' : '.',
772 (codec->capabilities & AV_CODEC_CAP_DRAW_HORIZ_BAND) ? 'B' : '.',
773 (codec->capabilities & AV_CODEC_CAP_DR1) ? 'D' : '.');
774
775 printf(" %-20s %s", codec->name, codec->long_name ? codec->long_name : "");
776 if (strcmp(codec->name, desc->name))
777 printf(" (codec %s)", desc->name);
778
779 printf("\n");
780 }
781 }
782 av_free(codecs);
783 return 0;
784 }
785
786 int show_decoders(void *optctx, const char *opt, const char *arg)
787 {
788 return print_codecs(SHOW_DECODER);
789 }
790
791 int show_encoders(void *optctx, const char *opt, const char *arg)
792 {
793 return print_codecs(SHOW_ENCODER);
794 }
795
796 int show_bsfs(void *optctx, const char *opt, const char *arg)
797 {
798 const AVBitStreamFilter *bsf = NULL;
799 void *opaque = NULL;
800
801 printf("Bitstream filters:\n");
802 while ((bsf = av_bsf_iterate(&opaque)))
803 printf("%s\n", bsf->name);
804 printf("\n");
805 return 0;
806 }
807
808 int show_filters(void *optctx, const char *opt, const char *arg)
809 {
810 #if CONFIG_AVFILTER
811 const AVFilter *filter = NULL;
812 char descr[64], *descr_cur;
813 void *opaque = NULL;
814 int i, j;
815 const AVFilterPad *pad;
816
817 printf("Filters:\n"
818 " T.. = Timeline support\n"
819 " .S. = Slice threading\n"
820 " A = Audio input/output\n"
821 " V = Video input/output\n"
822 " N = Dynamic number and/or type of input/output\n"
823 " | = Source or sink filter\n"
824 " ------\n");
825 while ((filter = av_filter_iterate(&opaque))) {
826 descr_cur = descr;
827 for (i = 0; i < 2; i++) {
828 unsigned nb_pads;
829 if (i) {
830 *(descr_cur++) = '-';
831 *(descr_cur++) = '>';
832 }
833 pad = i ? filter->outputs : filter->inputs;
834 nb_pads = avfilter_filter_pad_count(filter, i);
835 for (j = 0; j < nb_pads; j++) {
836 if (descr_cur >= descr + sizeof(descr) - 4)
837 break;
838 *(descr_cur++) = get_media_type_char(avfilter_pad_get_type(pad, j));
839 }
840 if (!j)
841 *(descr_cur++) = ((!i && (filter->flags & AVFILTER_FLAG_DYNAMIC_INPUTS)) ||
842 ( i && (filter->flags & AVFILTER_FLAG_DYNAMIC_OUTPUTS))) ? 'N' : '|';
843 }
844 *descr_cur = 0;
845 printf(" %c%c %-17s %-10s %s\n",
846 filter->flags & AVFILTER_FLAG_SUPPORT_TIMELINE ? 'T' : '.',
847 filter->flags & AVFILTER_FLAG_SLICE_THREADS ? 'S' : '.',
848 filter->name, descr, filter->description);
849 }
850 #else
851 printf("No filters available: libavfilter disabled\n");
852 #endif
853 return 0;
854 }
855
856 static int is_device(const AVClass *avclass)
857 {
858 if (!avclass)
859 return 0;
860 return AV_IS_INPUT_DEVICE(avclass->category) || AV_IS_OUTPUT_DEVICE(avclass->category);
861 }
862
863 static int show_formats_devices(void *optctx, const char *opt, const char *arg, int device_only, int muxdemuxers)
864 {
865 void *ifmt_opaque = NULL;
866 const AVInputFormat *ifmt = NULL;
867 void *ofmt_opaque = NULL;
868 const AVOutputFormat *ofmt = NULL;
869 const char *last_name;
870 int is_dev;
871 const char *is_device_placeholder = device_only ? "" : ".";
872
873 printf("%s:\n"
874 " D.%s = Demuxing supported\n"
875 " .E%s = Muxing supported\n"
876 "%s"
877 " ---\n",
878 device_only ? "Devices" : "Formats",
879 is_device_placeholder, is_device_placeholder,
880 device_only ? "": " ..d = Is a device\n");
881
882 last_name = "000";
883 for (;;) {
884 int decode = 0;
885 int encode = 0;
886 int device = 0;
887 const char *name = NULL;
888 const char *long_name = NULL;
889
890 if (muxdemuxers != SHOW_DEMUXERS) {
891 ofmt_opaque = NULL;
892 while ((ofmt = av_muxer_iterate(&ofmt_opaque))) {
893 is_dev = is_device(ofmt->priv_class);
894 if (!is_dev && device_only)
895 continue;
896 if ((!name || strcmp(ofmt->name, name) < 0) &&
897 strcmp(ofmt->name, last_name) > 0) {
898 name = ofmt->name;
899 long_name = ofmt->long_name;
900 encode = 1;
901 device = is_dev;
902 }
903 }
904 }
905 if (muxdemuxers != SHOW_MUXERS) {
906 ifmt_opaque = NULL;
907 while ((ifmt = av_demuxer_iterate(&ifmt_opaque))) {
908 is_dev = is_device(ifmt->priv_class);
909 if (!is_dev && device_only)
910 continue;
911 if ((!name || strcmp(ifmt->name, name) < 0) &&
912 strcmp(ifmt->name, last_name) > 0) {
913 name = ifmt->name;
914 long_name = ifmt->long_name;
915 encode = 0;
916 device = is_dev;
917 }
918 if (name && strcmp(ifmt->name, name) == 0) {
919 decode = 1;
920 device = is_dev;
921 }
922 }
923 }
924 if (!name)
925 break;
926 last_name = name;
927
928 printf(" %c%c%s %-15s %s\n",
929 decode ? 'D' : ' ',
930 encode ? 'E' : ' ',
931 device_only ? "" : (device ? "d" : " "),
932 name,
933 long_name ? long_name : " ");
934 }
935 return 0;
936 }
937
938 int show_formats(void *optctx, const char *opt, const char *arg)
939 {
940 return show_formats_devices(optctx, opt, arg, 0, SHOW_DEFAULT);
941 }
942
943 int show_muxers(void *optctx, const char *opt, const char *arg)
944 {
945 return show_formats_devices(optctx, opt, arg, 0, SHOW_MUXERS);
946 }
947
948 int show_demuxers(void *optctx, const char *opt, const char *arg)
949 {
950 return show_formats_devices(optctx, opt, arg, 0, SHOW_DEMUXERS);
951 }
952
953 int show_devices(void *optctx, const char *opt, const char *arg)
954 {
955 return show_formats_devices(optctx, opt, arg, 1, SHOW_DEFAULT);
956 }
957
958 int show_protocols(void *optctx, const char *opt, const char *arg)
959 {
960 void *opaque = NULL;
961 const char *name;
962
963 printf("Supported file protocols:\n"
964 "Input:\n");
965 while ((name = avio_enum_protocols(&opaque, 0)))
966 printf(" %s\n", name);
967 printf("Output:\n");
968 while ((name = avio_enum_protocols(&opaque, 1)))
969 printf(" %s\n", name);
970 return 0;
971 }
972
973 int show_colors(void *optctx, const char *opt, const char *arg)
974 {
975 const char *name;
976 const uint8_t *rgb;
977 int i;
978
979 printf("%-32s #RRGGBB\n", "name");
980
981 for (i = 0; name = av_get_known_color_name(i, &rgb); i++)
982 printf("%-32s #%02x%02x%02x\n", name, rgb[0], rgb[1], rgb[2]);
983
984 return 0;
985 }
986
987 1 int show_pix_fmts(void *optctx, const char *opt, const char *arg)
988 {
989 1 const AVPixFmtDescriptor *pix_desc = NULL;
990
991 1 printf("Pixel formats:\n"
992 "I.... = Supported Input format for conversion\n"
993 ".O... = Supported Output format for conversion\n"
994 "..H.. = Hardware accelerated format\n"
995 "...P. = Paletted format\n"
996 "....B = Bitstream format\n"
997 "FLAGS NAME NB_COMPONENTS BITS_PER_PIXEL BIT_DEPTHS\n"
998 "-----\n");
999
1000 #if !CONFIG_SWSCALE
1001 # define sws_isSupportedInput(x) 0
1002 # define sws_isSupportedOutput(x) 0
1003 #endif
1004
1005
2/2
✓ Branch 1 taken 268 times.
✓ Branch 2 taken 1 times.
269 while ((pix_desc = av_pix_fmt_desc_next(pix_desc))) {
1006 268 av_unused enum AVPixelFormat pix_fmt = av_pix_fmt_desc_get_id(pix_desc);
1007
4/4
✓ Branch 0 taken 204 times.
✓ Branch 1 taken 64 times.
✓ Branch 2 taken 232 times.
✓ Branch 3 taken 36 times.
1340 printf("%c%c%c%c%c %-16s %d %3d %d",
1008 268 sws_isSupportedInput (pix_fmt) ? 'I' : '.',
1009 268 sws_isSupportedOutput(pix_fmt) ? 'O' : '.',
1010
2/2
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 251 times.
268 pix_desc->flags & AV_PIX_FMT_FLAG_HWACCEL ? 'H' : '.',
1011
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 267 times.
268 pix_desc->flags & AV_PIX_FMT_FLAG_PAL ? 'P' : '.',
1012 268 pix_desc->flags & AV_PIX_FMT_FLAG_BITSTREAM ? 'B' : '.',
1013 268 pix_desc->name,
1014
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 262 times.
268 pix_desc->nb_components,
1015 av_get_bits_per_pixel(pix_desc),
1016 268 pix_desc->comp[0].depth);
1017
1018
2/2
✓ Branch 0 taken 514 times.
✓ Branch 1 taken 268 times.
782 for (unsigned i = 1; i < pix_desc->nb_components; i++)
1019 514 printf("-%d", pix_desc->comp[i].depth);
1020 268 printf("\n");
1021 }
1022 1 return 0;
1023 }
1024
1025 int show_layouts(void *optctx, const char *opt, const char *arg)
1026 {
1027 const AVChannelLayout *ch_layout;
1028 void *iter = NULL;
1029 char buf[128], buf2[128];
1030 int i = 0;
1031
1032 printf("Individual channels:\n"
1033 "NAME DESCRIPTION\n");
1034 for (i = 0; i < 63; i++) {
1035 av_channel_name(buf, sizeof(buf), i);
1036 if (strstr(buf, "USR"))
1037 continue;
1038 av_channel_description(buf2, sizeof(buf2), i);
1039 printf("%-14s %s\n", buf, buf2);
1040 }
1041 printf("\nStandard channel layouts:\n"
1042 "NAME DECOMPOSITION\n");
1043 while (ch_layout = av_channel_layout_standard(&iter)) {
1044 av_channel_layout_describe(ch_layout, buf, sizeof(buf));
1045 printf("%-14s ", buf);
1046 for (i = 0; i < 63; i++) {
1047 int idx = av_channel_layout_index_from_channel(ch_layout, i);
1048 if (idx >= 0) {
1049 av_channel_name(buf2, sizeof(buf2), i);
1050 printf("%s%s", idx ? "+" : "", buf2);
1051 }
1052 }
1053 printf("\n");
1054 }
1055 return 0;
1056 }
1057
1058 int show_sample_fmts(void *optctx, const char *opt, const char *arg)
1059 {
1060 int i;
1061 char fmt_str[128];
1062 for (i = -1; i < AV_SAMPLE_FMT_NB; i++)
1063 printf("%s\n", av_get_sample_fmt_string(fmt_str, sizeof(fmt_str), i));
1064 return 0;
1065 }
1066
1067 int show_dispositions(void *optctx, const char *opt, const char *arg)
1068 {
1069 for (int i = 0; i < 32; i++) {
1070 const char *str = av_disposition_to_string(1U << i);
1071 if (str)
1072 printf("%s\n", str);
1073 }
1074 return 0;
1075 }
1076
1077 8636 int opt_cpuflags(void *optctx, const char *opt, const char *arg)
1078 {
1079 int ret;
1080 8636 unsigned flags = av_get_cpu_flags();
1081
1082
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8636 times.
8636 if ((ret = av_parse_cpu_caps(&flags, arg)) < 0)
1083 return ret;
1084
1085 8636 av_force_cpu_flags(flags);
1086 8636 return 0;
1087 }
1088
1089 int opt_cpucount(void *optctx, const char *opt, const char *arg)
1090 {
1091 int ret;
1092 int count;
1093
1094 static const AVOption opts[] = {
1095 {"count", NULL, 0, AV_OPT_TYPE_INT, { .i64 = -1}, -1, INT_MAX},
1096 {NULL},
1097 };
1098 static const AVClass class = {
1099 .class_name = "cpucount",
1100 .item_name = av_default_item_name,
1101 .option = opts,
1102 .version = LIBAVUTIL_VERSION_INT,
1103 };
1104 const AVClass *pclass = &class;
1105
1106 ret = av_opt_eval_int(&pclass, opts, arg, &count);
1107
1108 if (!ret) {
1109 av_cpu_force_count(count);
1110 }
1111
1112 return ret;
1113 }
1114
1115 static void expand_filename_template(AVBPrint *bp, const char *template,
1116 struct tm *tm)
1117 {
1118 int c;
1119
1120 while ((c = *(template++))) {
1121 if (c == '%') {
1122 if (!(c = *(template++)))
1123 break;
1124 switch (c) {
1125 case 'p':
1126 av_bprintf(bp, "%s", program_name);
1127 break;
1128 case 't':
1129 av_bprintf(bp, "%04d%02d%02d-%02d%02d%02d",
1130 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
1131 tm->tm_hour, tm->tm_min, tm->tm_sec);
1132 break;
1133 case '%':
1134 av_bprint_chars(bp, c, 1);
1135 break;
1136 }
1137 } else {
1138 av_bprint_chars(bp, c, 1);
1139 }
1140 }
1141 }
1142
1143 static void log_callback_report(void *ptr, int level, const char *fmt, va_list vl)
1144 {
1145 va_list vl2;
1146 char line[1024];
1147 static int print_prefix = 1;
1148
1149 va_copy(vl2, vl);
1150 av_log_default_callback(ptr, level, fmt, vl);
1151 av_log_format_line(ptr, level, fmt, vl2, line, sizeof(line), &print_prefix);
1152 va_end(vl2);
1153 if (report_file_level >= level) {
1154 fputs(line, report_file);
1155 fflush(report_file);
1156 }
1157 }
1158
1159 int init_report(const char *env, FILE **file)
1160 {
1161 char *filename_template = NULL;
1162 char *key, *val;
1163 int ret, count = 0;
1164 int prog_loglevel, envlevel = 0;
1165 time_t now;
1166 struct tm *tm;
1167 AVBPrint filename;
1168
1169 if (report_file) /* already opened */
1170 return 0;
1171 time(&now);
1172 tm = localtime(&now);
1173
1174 while (env && *env) {
1175 if ((ret = av_opt_get_key_value(&env, "=", ":", 0, &key, &val)) < 0) {
1176 if (count)
1177 av_log(NULL, AV_LOG_ERROR,
1178 "Failed to parse FFREPORT environment variable: %s\n",
1179 av_err2str(ret));
1180 break;
1181 }
1182 if (*env)
1183 env++;
1184 count++;
1185 if (!strcmp(key, "file")) {
1186 av_free(filename_template);
1187 filename_template = val;
1188 val = NULL;
1189 } else if (!strcmp(key, "level")) {
1190 char *tail;
1191 report_file_level = strtol(val, &tail, 10);
1192 if (*tail) {
1193 av_log(NULL, AV_LOG_FATAL, "Invalid report file level\n");
1194 av_free(key);
1195 av_free(val);
1196 av_free(filename_template);
1197 return AVERROR(EINVAL);
1198 }
1199 envlevel = 1;
1200 } else {
1201 av_log(NULL, AV_LOG_ERROR, "Unknown key '%s' in FFREPORT\n", key);
1202 }
1203 av_free(val);
1204 av_free(key);
1205 }
1206
1207 av_bprint_init(&filename, 0, AV_BPRINT_SIZE_AUTOMATIC);
1208 expand_filename_template(&filename,
1209 av_x_if_null(filename_template, "%p-%t.log"), tm);
1210 av_free(filename_template);
1211 if (!av_bprint_is_complete(&filename)) {
1212 av_log(NULL, AV_LOG_ERROR, "Out of memory building report file name\n");
1213 return AVERROR(ENOMEM);
1214 }
1215
1216 prog_loglevel = av_log_get_level();
1217 if (!envlevel)
1218 report_file_level = FFMAX(report_file_level, prog_loglevel);
1219
1220 report_file = fopen_utf8(filename.str, "w");
1221 if (!report_file) {
1222 int ret = AVERROR(errno);
1223 av_log(NULL, AV_LOG_ERROR, "Failed to open report \"%s\": %s\n",
1224 filename.str, strerror(errno));
1225 return ret;
1226 }
1227 av_log_set_callback(log_callback_report);
1228 av_log(NULL, AV_LOG_INFO,
1229 "%s started on %04d-%02d-%02d at %02d:%02d:%02d\n"
1230 "Report written to \"%s\"\n"
1231 "Log level: %d\n",
1232 program_name,
1233 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
1234 tm->tm_hour, tm->tm_min, tm->tm_sec,
1235 filename.str, report_file_level);
1236 av_bprint_finalize(&filename, NULL);
1237
1238 if (file)
1239 *file = report_file;
1240
1241 return 0;
1242 }
1243
1244 int opt_report(void *optctx, const char *opt, const char *arg)
1245 {
1246 return init_report(NULL, NULL);
1247 }
1248
1249 int opt_max_alloc(void *optctx, const char *opt, const char *arg)
1250 {
1251 char *tail;
1252 size_t max;
1253
1254 max = strtol(arg, &tail, 10);
1255 if (*tail) {
1256 av_log(NULL, AV_LOG_FATAL, "Invalid max_alloc \"%s\".\n", arg);
1257 return AVERROR(EINVAL);
1258 }
1259 av_max_alloc(max);
1260 return 0;
1261 }
1262
1263 148 int opt_loglevel(void *optctx, const char *opt, const char *arg)
1264 {
1265 148 const struct { const char *name; int level; } log_levels[] = {
1266 { "quiet" , AV_LOG_QUIET },
1267 { "panic" , AV_LOG_PANIC },
1268 { "fatal" , AV_LOG_FATAL },
1269 { "error" , AV_LOG_ERROR },
1270 { "warning", AV_LOG_WARNING },
1271 { "info" , AV_LOG_INFO },
1272 { "verbose", AV_LOG_VERBOSE },
1273 { "debug" , AV_LOG_DEBUG },
1274 { "trace" , AV_LOG_TRACE },
1275 };
1276 const char *token;
1277 char *tail;
1278 148 int flags = av_log_get_flags();
1279 148 int level = av_log_get_level();
1280 148 int cmd, i = 0;
1281
1282
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 148 times.
148 av_assert0(arg);
1283
1/2
✓ Branch 0 taken 148 times.
✗ Branch 1 not taken.
148 while (*arg) {
1284 148 token = arg;
1285
2/4
✓ Branch 0 taken 148 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 148 times.
148 if (*token == '+' || *token == '-') {
1286 cmd = *token++;
1287 } else {
1288 148 cmd = 0;
1289 }
1290
2/4
✓ Branch 0 taken 148 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 148 times.
✗ Branch 3 not taken.
148 if (!i && !cmd) {
1291 148 flags = 0; /* missing relative prefix, build absolute value */
1292 }
1293
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 148 times.
148 if (av_strstart(token, "repeat", &arg)) {
1294 if (cmd == '-') {
1295 flags |= AV_LOG_SKIP_REPEATED;
1296 } else {
1297 flags &= ~AV_LOG_SKIP_REPEATED;
1298 }
1299
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 148 times.
148 } else if (av_strstart(token, "level", &arg)) {
1300 if (cmd == '-') {
1301 flags &= ~AV_LOG_PRINT_LEVEL;
1302 } else {
1303 flags |= AV_LOG_PRINT_LEVEL;
1304 }
1305
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 148 times.
148 } else if (av_strstart(token, "time", &arg)) {
1306 if (cmd == '-') {
1307 flags &= ~AV_LOG_PRINT_TIME;
1308 } else {
1309 flags |= AV_LOG_PRINT_TIME;
1310 }
1311
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 148 times.
148 } else if (av_strstart(token, "datetime", &arg)) {
1312 if (cmd == '-') {
1313 flags &= ~AV_LOG_PRINT_DATETIME;
1314 } else {
1315 flags |= AV_LOG_PRINT_DATETIME;
1316 }
1317 } else {
1318 148 break;
1319 }
1320 i++;
1321 }
1322
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 148 times.
148 if (!*arg) {
1323 goto end;
1324
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 148 times.
148 } else if (*arg == '+') {
1325 arg++;
1326
1/2
✓ Branch 0 taken 148 times.
✗ Branch 1 not taken.
148 } else if (!i) {
1327 148 flags = av_log_get_flags(); /* level value without prefix, reset flags */
1328 }
1329
1330
2/2
✓ Branch 0 taken 834 times.
✓ Branch 1 taken 64 times.
898 for (i = 0; i < FF_ARRAY_ELEMS(log_levels); i++) {
1331
2/2
✓ Branch 0 taken 84 times.
✓ Branch 1 taken 750 times.
834 if (!strcmp(log_levels[i].name, arg)) {
1332 84 level = log_levels[i].level;
1333 84 goto end;
1334 }
1335 }
1336
1337 64 level = strtol(arg, &tail, 10);
1338
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 64 times.
64 if (*tail) {
1339 av_log(NULL, AV_LOG_FATAL, "Invalid loglevel \"%s\". "
1340 "Possible levels are numbers or:\n", arg);
1341 for (i = 0; i < FF_ARRAY_ELEMS(log_levels); i++)
1342 av_log(NULL, AV_LOG_FATAL, "\"%s\"\n", log_levels[i].name);
1343 av_log(NULL, AV_LOG_FATAL, "Possible flags are:\n");
1344 av_log(NULL, AV_LOG_FATAL, "\"repeat\"\n");
1345 av_log(NULL, AV_LOG_FATAL, "\"level\"\n");
1346 av_log(NULL, AV_LOG_FATAL, "\"time\"\n");
1347 av_log(NULL, AV_LOG_FATAL, "\"datetime\"\n");
1348 return AVERROR(EINVAL);
1349 }
1350
1351 64 end:
1352 148 av_log_set_flags(flags);
1353 148 av_log_set_level(level);
1354 148 return 0;
1355 }
1356
1357 #if CONFIG_AVDEVICE
1358 1 static void print_device_list(const AVDeviceInfoList *device_list)
1359 {
1360 // print devices
1361
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 for (int i = 0; i < device_list->nb_devices; i++) {
1362 1 const AVDeviceInfo *device = device_list->devices[i];
1363 1 printf("%c %s [%s] (", device_list->default_device == i ? '*' : ' ',
1364
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 device->device_name, device->device_description);
1365
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (device->nb_media_types > 0) {
1366 for (int j = 0; j < device->nb_media_types; ++j) {
1367 const char* media_type = av_get_media_type_string(device->media_types[j]);
1368 if (j > 0)
1369 printf(", ");
1370 printf("%s", media_type ? media_type : "unknown");
1371 }
1372 } else {
1373 1 printf("none");
1374 }
1375 1 printf(")\n");
1376 }
1377 1 }
1378
1379 1 static int print_device_sources(const AVInputFormat *fmt, AVDictionary *opts)
1380 {
1381 int ret;
1382 1 AVDeviceInfoList *device_list = NULL;
1383
1384
4/10
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
1 if (!fmt || !fmt->priv_class || !AV_IS_INPUT_DEVICE(fmt->priv_class->category))
1385 return AVERROR(EINVAL);
1386
1387 1 printf("Auto-detected sources for %s:\n", fmt->name);
1388
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 if ((ret = avdevice_list_input_sources(fmt, NULL, opts, &device_list)) < 0) {
1389 printf("Cannot list sources: %s\n", av_err2str(ret));
1390 goto fail;
1391 }
1392
1393 1 print_device_list(device_list);
1394
1395 1 fail:
1396 1 avdevice_free_list_devices(&device_list);
1397 1 return ret;
1398 }
1399
1400 static int print_device_sinks(const AVOutputFormat *fmt, AVDictionary *opts)
1401 {
1402 int ret;
1403 AVDeviceInfoList *device_list = NULL;
1404
1405 if (!fmt || !fmt->priv_class || !AV_IS_OUTPUT_DEVICE(fmt->priv_class->category))
1406 return AVERROR(EINVAL);
1407
1408 printf("Auto-detected sinks for %s:\n", fmt->name);
1409 if ((ret = avdevice_list_output_sinks(fmt, NULL, opts, &device_list)) < 0) {
1410 printf("Cannot list sinks: %s\n", av_err2str(ret));
1411 goto fail;
1412 }
1413
1414 print_device_list(device_list);
1415
1416 fail:
1417 avdevice_free_list_devices(&device_list);
1418 return ret;
1419 }
1420
1421 1 static int show_sinks_sources_parse_arg(const char *arg, char **dev, AVDictionary **opts)
1422 {
1423 int ret;
1424
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (arg) {
1425 1 char *opts_str = NULL;
1426
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
1 av_assert0(dev && opts);
1427 1 *dev = av_strdup(arg);
1428
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!*dev)
1429 return AVERROR(ENOMEM);
1430
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if ((opts_str = strchr(*dev, ','))) {
1431 *(opts_str++) = '\0';
1432 if (opts_str[0] && ((ret = av_dict_parse_string(opts, opts_str, "=", ":", 0)) < 0)) {
1433 av_freep(dev);
1434 return ret;
1435 }
1436 }
1437 } else
1438 printf("\nDevice name is not provided.\n"
1439 "You can pass devicename[,opt1=val1[,opt2=val2...]] as an argument.\n\n");
1440 1 return 0;
1441 }
1442
1443 1 int show_sources(void *optctx, const char *opt, const char *arg)
1444 {
1445 1 const AVInputFormat *fmt = NULL;
1446 1 char *dev = NULL;
1447 1 AVDictionary *opts = NULL;
1448 1 int ret = 0;
1449 1 int error_level = av_log_get_level();
1450
1451 1 av_log_set_level(AV_LOG_WARNING);
1452
1453
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 if ((ret = show_sinks_sources_parse_arg(arg, &dev, &opts)) < 0)
1454 goto fail;
1455
1456 do {
1457 4 fmt = av_input_audio_device_next(fmt);
1458
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1 times.
4 if (fmt) {
1459
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
3 if (!strcmp(fmt->name, "lavfi"))
1460 1 continue; //it's pointless to probe lavfi
1461
3/4
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 1 times.
2 if (dev && !av_match_name(dev, fmt->name))
1462 1 continue;
1463 1 print_device_sources(fmt, opts);
1464 }
1465
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1 times.
4 } while (fmt);
1466 do {
1467 6 fmt = av_input_video_device_next(fmt);
1468
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 1 times.
6 if (fmt) {
1469
2/4
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 5 times.
✗ Branch 4 not taken.
5 if (dev && !av_match_name(dev, fmt->name))
1470 5 continue;
1471 print_device_sources(fmt, opts);
1472 }
1473
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 1 times.
6 } while (fmt);
1474 1 fail:
1475 1 av_dict_free(&opts);
1476 1 av_free(dev);
1477 1 av_log_set_level(error_level);
1478 1 return ret;
1479 }
1480
1481 int show_sinks(void *optctx, const char *opt, const char *arg)
1482 {
1483 const AVOutputFormat *fmt = NULL;
1484 char *dev = NULL;
1485 AVDictionary *opts = NULL;
1486 int ret = 0;
1487 int error_level = av_log_get_level();
1488
1489 av_log_set_level(AV_LOG_WARNING);
1490
1491 if ((ret = show_sinks_sources_parse_arg(arg, &dev, &opts)) < 0)
1492 goto fail;
1493
1494 do {
1495 fmt = av_output_audio_device_next(fmt);
1496 if (fmt) {
1497 if (dev && !av_match_name(dev, fmt->name))
1498 continue;
1499 print_device_sinks(fmt, opts);
1500 }
1501 } while (fmt);
1502 do {
1503 fmt = av_output_video_device_next(fmt);
1504 if (fmt) {
1505 if (dev && !av_match_name(dev, fmt->name))
1506 continue;
1507 print_device_sinks(fmt, opts);
1508 }
1509 } while (fmt);
1510 fail:
1511 av_dict_free(&opts);
1512 av_free(dev);
1513 av_log_set_level(error_level);
1514 return ret;
1515 }
1516 #endif /* CONFIG_AVDEVICE */
1517