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