FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/fftools/opt_common.c
Date: 2026-05-02 03:33:10
Exec Total Coverage
Lines: 131 773 16.9%
Functions: 10 53 18.9%
Branches: 110 637 17.3%

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