FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/fftools/opt_common.c
Date: 2025-10-10 03:51:19
Exec Total Coverage
Lines: 78 773 10.1%
Functions: 6 53 11.3%
Branches: 79 637 12.4%

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