FFmpeg coverage


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