FFmpegKit Android API 4.5
fftools_cmdutils.c
Go to the documentation of this file.
1/*
2 * Various utilities for command line tools
3 * Copyright (c) 2000-2003 Fabrice Bellard
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 * CHANGES 01.2021
24 * - NDK r22 incompatibility issues regarding INT64_MAX fixed
25 *
26 * CHANGES 01.2020
27 * - ffprobe support changes
28 * - (optindex < argc) validation in parse_options() method updated with (optindex >= argc) check
29 *
30 * CHANGES 12.2019
31 * - Concurrent execution support
32 * - log_callback_report method re-added to fix -report option issues
33 *
34 * CHANGES 08.2018
35 * --------------------------------------------------------
36 * - fftools_ prefix added to the file name and parent header
37 *
38 * CHANGES 07.2018
39 * --------------------------------------------------------
40 * - Unused headers removed
41 * - Parentheses placed around assignments in conditions to prevent -Wparentheses warning
42 * - exit_program updated with longjmp, disabling exit
43 * - longjmp_value added to store exit code
44 * - (optindex < argc) validation added before accessing argv[optindex] inside split_commandline()
45 * and parse_options()
46 * - All av_log_set_callback invocations updated to set ffmpegkit_log_callback_function from ffmpegkit.c. Unused
47 * log_callback_help and log_callback_help methods removed
48 * - (idx + 1 < argc) validation added in parse_loglevel()
49 */
50
51#include <string.h>
52#include <stdint.h>
53#include <stdlib.h>
54#include <errno.h>
55#include <math.h>
56
57#include "ffmpegkit_exception.h"
58
59/* Include only the enabled headers since some compilers (namely, Sun
60 Studio) will not omit unused inline functions and create undefined
61 references to libraries that are not being built. */
62
63#include "config.h"
64#include "libavformat/avformat.h"
65#include "libavfilter/avfilter.h"
66#include "libavdevice/avdevice.h"
67#include "libswscale/swscale.h"
68#include "libswresample/swresample.h"
69#include "libavutil/attributes.h"
70#include "libavutil/avassert.h"
71#include "libavutil/avstring.h"
72#include "libavutil/bprint.h"
73#include "libavutil/channel_layout.h"
74#include "libavutil/display.h"
75#include "libavutil/mathematics.h"
76#include "libavutil/imgutils.h"
77#include "libavutil/libm.h"
78#include "libavutil/parseutils.h"
79#include "libavutil/pixdesc.h"
80#include "libavutil/eval.h"
81#include "libavutil/dict.h"
82#include "libavutil/opt.h"
83#include "libavutil/cpu.h"
84#include "libavutil/ffversion.h"
85#include "libavutil/version.h"
86#include "libavcodec/bsf.h"
87#include "fftools_cmdutils.h"
88#if HAVE_SYS_RESOURCE_H
89#include <sys/time.h>
90#include <sys/resource.h>
91#endif
92#ifdef _WIN32
93#include <windows.h>
94#endif
95
96static int init_report(const char *env);
97extern void ffmpegkit_log_callback_function(void *ptr, int level, const char* format, va_list vargs);
98extern void (*report_callback)(int, float, float, int64_t, int, double, double);
99
100__thread char *program_name;
102
103__thread AVDictionary *sws_dict;
104__thread AVDictionary *swr_opts;
105__thread AVDictionary *format_opts, *codec_opts, *resample_opts;
106
108int report_file_level = AV_LOG_DEBUG;
109__thread int hide_banner = 0;
110__thread volatile int longjmp_value = 0;
111
116};
117
118void uninit_opts(void)
119{
120 av_dict_free(&swr_opts);
121 av_dict_free(&sws_dict);
122 av_dict_free(&format_opts);
123 av_dict_free(&codec_opts);
124 av_dict_free(&resample_opts);
125}
126
127void log_callback_report(void *ptr, int level, const char *fmt, va_list vl)
128{
129 va_list vl2;
130 char line[1024];
131 static int print_prefix = 1;
132
133 va_copy(vl2, vl);
134 if (report_callback == NULL) {
135 av_log_default_callback(ptr, level, fmt, vl);
136 } else {
137 ffmpegkit_log_callback_function(ptr, level, fmt, vl);
138 }
139 av_log_format_line(ptr, level, fmt, vl2, line, sizeof(line), &print_prefix);
140 va_end(vl2);
141 if (report_file_level >= level) {
142 fputs(line, report_file);
143 fflush(report_file);
144 }
145}
146
147void init_dynload(void)
148{
149#if HAVE_SETDLLDIRECTORY && defined(_WIN32)
150 /* Calling SetDllDirectory with the empty string (but not NULL) removes the
151 * current working directory from the DLL search path as a security pre-caution. */
152 SetDllDirectory("");
153#endif
154}
155
156static __thread void (*program_exit)(int ret);
157
158void register_exit(void (*cb)(int ret))
159{
160 program_exit = cb;
161}
162
163void exit_program(int ret)
164{
165 if (program_exit)
166 program_exit(ret);
167
168 // exit disabled and replaced with longjmp, exit value stored in longjmp_value
169 // exit(ret);
170 longjmp_value = ret;
171 longjmp(ex_buf__, ret);
172}
173
174double parse_number_or_die(const char *context, const char *numstr, int type,
175 double min, double max)
176{
177 char *tail;
178 const char *error;
179 double d = av_strtod(numstr, &tail);
180 if (*tail)
181 error = "Expected number for %s but found: %s\n";
182 else if (d < min || d > max)
183 error = "The value for %s was %s which is not within %f - %f\n";
184 else if (type == OPT_INT64 && (int64_t)d != d)
185 error = "Expected int64 for %s but found %s\n";
186 else if (type == OPT_INT && (int)d != d)
187 error = "Expected int for %s but found %s\n";
188 else
189 return d;
190 av_log(NULL, AV_LOG_FATAL, error, context, numstr, min, max);
191 exit_program(1);
192 return 0;
193}
194
195int64_t parse_time_or_die(const char *context, const char *timestr,
196 int is_duration)
197{
198 int64_t us;
199 if (av_parse_time(&us, timestr, is_duration) < 0) {
200 av_log(NULL, AV_LOG_FATAL, "Invalid %s specification for %s: %s\n",
201 is_duration ? "duration" : "date", context, timestr);
202 exit_program(1);
203 }
204 return us;
205}
206
207void show_help_options(const OptionDef *options, const char *msg, int req_flags,
208 int rej_flags, int alt_flags)
209{
210 const OptionDef *po;
211 int first;
212
213 first = 1;
214 for (po = options; po->name; po++) {
215 char buf[128];
216
217 if (((po->flags & req_flags) != req_flags) ||
218 (alt_flags && !(po->flags & alt_flags)) ||
219 (po->flags & rej_flags))
220 continue;
221
222 if (first) {
223 av_log(NULL, AV_LOG_STDERR, "%s\n", msg);
224 first = 0;
225 }
226 av_strlcpy(buf, po->name, sizeof(buf));
227 if (po->argname) {
228 av_strlcat(buf, " ", sizeof(buf));
229 av_strlcat(buf, po->argname, sizeof(buf));
230 }
231 av_log(NULL, AV_LOG_STDERR, "-%-17s %s\n", buf, po->help);
232 }
233 av_log(NULL, AV_LOG_STDERR, "\n");
234}
235
236void show_help_children(const AVClass *class, int flags)
237{
238 void *iter = NULL;
239 const AVClass *child;
240 if (class->option) {
241 av_opt_show2(&class, NULL, flags, 0);
242 av_log(NULL, AV_LOG_STDERR, "\n");
243 }
244
245 while ((child = av_opt_child_class_iterate(class, &iter)))
246 show_help_children(child, flags);
247}
248
249static const OptionDef *find_option(const OptionDef *po, const char *name)
250{
251 while (po->name) {
252 const char *end;
253 if (av_strstart(name, po->name, &end) && (!*end || *end == ':'))
254 break;
255 po++;
256 }
257 return po;
258}
259
260/* _WIN32 means using the windows libc - cygwin doesn't define that
261 * by default. HAVE_COMMANDLINETOARGVW is true on cygwin, while
262 * it doesn't provide the actual command line via GetCommandLineW(). */
263#if HAVE_COMMANDLINETOARGVW && defined(_WIN32)
264#include <shellapi.h>
265/* Will be leaked on exit */
266static char** win32_argv_utf8 = NULL;
267static int win32_argc = 0;
268
276static void prepare_app_arguments(int *argc_ptr, char ***argv_ptr)
277{
278 char *argstr_flat;
279 wchar_t **argv_w;
280 int i, buffsize = 0, offset = 0;
281
282 if (win32_argv_utf8) {
283 *argc_ptr = win32_argc;
284 *argv_ptr = win32_argv_utf8;
285 return;
286 }
287
288 win32_argc = 0;
289 argv_w = CommandLineToArgvW(GetCommandLineW(), &win32_argc);
290 if (win32_argc <= 0 || !argv_w)
291 return;
292
293 /* determine the UTF-8 buffer size (including NULL-termination symbols) */
294 for (i = 0; i < win32_argc; i++)
295 buffsize += WideCharToMultiByte(CP_UTF8, 0, argv_w[i], -1,
296 NULL, 0, NULL, NULL);
297
298 win32_argv_utf8 = av_mallocz(sizeof(char *) * (win32_argc + 1) + buffsize);
299 argstr_flat = (char *)win32_argv_utf8 + sizeof(char *) * (win32_argc + 1);
300 if (!win32_argv_utf8) {
301 LocalFree(argv_w);
302 return;
303 }
304
305 for (i = 0; i < win32_argc; i++) {
306 win32_argv_utf8[i] = &argstr_flat[offset];
307 offset += WideCharToMultiByte(CP_UTF8, 0, argv_w[i], -1,
308 &argstr_flat[offset],
309 buffsize - offset, NULL, NULL);
310 }
311 win32_argv_utf8[i] = NULL;
312 LocalFree(argv_w);
313
314 *argc_ptr = win32_argc;
315 *argv_ptr = win32_argv_utf8;
316}
317#else
318static inline void prepare_app_arguments(int *argc_ptr, char ***argv_ptr)
319{
320 /* nothing to do */
321}
322#endif /* HAVE_COMMANDLINETOARGVW */
323
324static int write_option(void *optctx, const OptionDef *po, const char *opt,
325 const char *arg)
326{
327 /* new-style options contain an offset into optctx, old-style address of
328 * a global var*/
329 void *dst = po->flags & (OPT_OFFSET | OPT_SPEC) ?
330 (uint8_t *)optctx + po->u.off : po->u.dst_ptr;
331 int *dstcount;
332
333 if (po->flags & OPT_SPEC) {
334 SpecifierOpt **so = dst;
335 char *p = strchr(opt, ':');
336 char *str;
337
338 dstcount = (int *)(so + 1);
339 *so = grow_array(*so, sizeof(**so), dstcount, *dstcount + 1);
340 str = av_strdup(p ? p + 1 : "");
341 if (!str)
342 return AVERROR(ENOMEM);
343 (*so)[*dstcount - 1].specifier = str;
344 dst = &(*so)[*dstcount - 1].u;
345 }
346
347 if (po->flags & OPT_STRING) {
348 char *str;
349 str = av_strdup(arg);
350 av_freep(dst);
351 if (!str)
352 return AVERROR(ENOMEM);
353 *(char **)dst = str;
354 } else if (po->flags & OPT_BOOL || po->flags & OPT_INT) {
355 *(int *)dst = parse_number_or_die(opt, arg, OPT_INT64, INT_MIN, INT_MAX);
356 } else if (po->flags & OPT_INT64) {
357 *(int64_t *)dst = parse_number_or_die(opt, arg, OPT_INT64, INT64_MIN, (double)INT64_MAX);
358 } else if (po->flags & OPT_TIME) {
359 *(int64_t *)dst = parse_time_or_die(opt, arg, 1);
360 } else if (po->flags & OPT_FLOAT) {
361 *(float *)dst = parse_number_or_die(opt, arg, OPT_FLOAT, -INFINITY, INFINITY);
362 } else if (po->flags & OPT_DOUBLE) {
363 *(double *)dst = parse_number_or_die(opt, arg, OPT_DOUBLE, -INFINITY, INFINITY);
364 } else if (po->u.func_arg) {
365 int ret = po->u.func_arg(optctx, opt, arg);
366 if (ret < 0) {
367 av_log(NULL, AV_LOG_ERROR,
368 "Failed to set value '%s' for option '%s': %s\n",
369 arg, opt, av_err2str(ret));
370 return ret;
371 }
372 }
373 if (po->flags & OPT_EXIT)
374 exit_program(0);
375
376 return 0;
377}
378
379int parse_option(void *optctx, const char *opt, const char *arg,
380 const OptionDef *options)
381{
382 const OptionDef *po;
383 int ret;
384
385 po = find_option(options, opt);
386 if (!po->name && opt[0] == 'n' && opt[1] == 'o') {
387 /* handle 'no' bool option */
388 po = find_option(options, opt + 2);
389 if ((po->name && (po->flags & OPT_BOOL)))
390 arg = "0";
391 } else if (po->flags & OPT_BOOL)
392 arg = "1";
393
394 if (!po->name)
395 po = find_option(options, "default");
396 if (!po->name) {
397 av_log(NULL, AV_LOG_ERROR, "Unrecognized option '%s'\n", opt);
398 return AVERROR(EINVAL);
399 }
400 if (po->flags & HAS_ARG && !arg) {
401 av_log(NULL, AV_LOG_ERROR, "Missing argument for option '%s'\n", opt);
402 return AVERROR(EINVAL);
403 }
404
405 ret = write_option(optctx, po, opt, arg);
406 if (ret < 0)
407 return ret;
408
409 return !!(po->flags & HAS_ARG);
410}
411
412void parse_options(void *optctx, int argc, char **argv, const OptionDef *options,
413 void (*parse_arg_function)(void *, const char*))
414{
415 const char *opt;
416 int optindex, handleoptions = 1, ret;
417
418 /* perform system-dependent conversions for arguments list */
419 prepare_app_arguments(&argc, &argv);
420
421 /* parse options */
422 optindex = 1;
423 while (optindex < argc) {
424 opt = argv[optindex++];
425
426 if (handleoptions && opt[0] == '-' && opt[1] != '\0') {
427 if (opt[1] == '-' && opt[2] == '\0') {
428 handleoptions = 0;
429 continue;
430 }
431 opt++;
432 if (optindex >= argc) {
433 if ((ret = parse_option(optctx, opt, NULL, options)) < 0)
434 exit_program(1);
435 } else {
436 if ((ret = parse_option(optctx, opt, argv[optindex], options)) < 0)
437 exit_program(1);
438 }
439 optindex += ret;
440 } else {
441 if (parse_arg_function)
442 parse_arg_function(optctx, opt);
443 }
444 }
445}
446
447int parse_optgroup(void *optctx, OptionGroup *g)
448{
449 int i, ret;
450
451 av_log(NULL, AV_LOG_DEBUG, "Parsing a group of options: %s %s.\n",
452 g->group_def->name, g->arg);
453
454 for (i = 0; i < g->nb_opts; i++) {
455 Option *o = &g->opts[i];
456
457 if (g->group_def->flags &&
458 !(g->group_def->flags & o->opt->flags)) {
459 av_log(NULL, AV_LOG_ERROR, "Option %s (%s) cannot be applied to "
460 "%s %s -- you are trying to apply an input option to an "
461 "output file or vice versa. Move this option before the "
462 "file it belongs to.\n", o->key, o->opt->help,
463 g->group_def->name, g->arg);
464 return AVERROR(EINVAL);
465 }
466
467 av_log(NULL, AV_LOG_DEBUG, "Applying option %s (%s) with argument %s.\n",
468 o->key, o->opt->help, o->val);
469
470 ret = write_option(optctx, o->opt, o->key, o->val);
471 if (ret < 0)
472 return ret;
473 }
474
475 av_log(NULL, AV_LOG_DEBUG, "Successfully parsed a group of options.\n");
476
477 return 0;
478}
479
480int locate_option(int argc, char **argv, const OptionDef *options,
481 const char *optname)
482{
483 const OptionDef *po;
484 int i;
485
486 for (i = 1; i < argc; i++) {
487 const char *cur_opt = argv[i];
488
489 if (*cur_opt++ != '-')
490 continue;
491
492 po = find_option(options, cur_opt);
493 if (!po->name && cur_opt[0] == 'n' && cur_opt[1] == 'o')
494 po = find_option(options, cur_opt + 2);
495
496 if ((!po->name && !strcmp(cur_opt, optname)) ||
497 (po->name && !strcmp(optname, po->name)))
498 return i;
499
500 if (!po->name || po->flags & HAS_ARG)
501 i++;
502 }
503 return 0;
504}
505
506static void dump_argument(const char *a)
507{
508 const unsigned char *p;
509
510 for (p = a; *p; p++)
511 if (!((*p >= '+' && *p <= ':') || (*p >= '@' && *p <= 'Z') ||
512 *p == '_' || (*p >= 'a' && *p <= 'z')))
513 break;
514 if (!*p) {
515 fputs(a, report_file);
516 return;
517 }
518 fputc('"', report_file);
519 for (p = a; *p; p++) {
520 if (*p == '\\' || *p == '"' || *p == '$' || *p == '`')
521 fprintf(report_file, "\\%c", *p);
522 else if (*p < ' ' || *p > '~')
523 fprintf(report_file, "\\x%02x", *p);
524 else
525 fputc(*p, report_file);
526 }
527 fputc('"', report_file);
528}
529
530static void check_options(const OptionDef *po)
531{
532 while (po->name) {
533 if (po->flags & OPT_PERFILE)
534 av_assert0(po->flags & (OPT_INPUT | OPT_OUTPUT));
535 po++;
536 }
537}
538
539void parse_loglevel(int argc, char **argv, const OptionDef *options)
540{
541 int idx = locate_option(argc, argv, options, "loglevel");
542 const char *env;
543
544 check_options(options);
545
546 if (!idx)
547 idx = locate_option(argc, argv, options, "v");
548 if (idx && (idx + 1 < argc) && argv[idx + 1])
549 opt_loglevel(NULL, "loglevel", argv[idx + 1]);
550 idx = locate_option(argc, argv, options, "report");
551 if ((env = getenv("FFREPORT")) || idx) {
552 init_report(env);
553 if (report_file) {
554 int i;
555 fprintf(report_file, "Command line:\n");
556 for (i = 0; i < argc; i++) {
557 dump_argument(argv[i]);
558 fputc(i < argc - 1 ? ' ' : '\n', report_file);
559 }
560 fflush(report_file);
561 }
562 }
563 idx = locate_option(argc, argv, options, "hide_banner");
564 if (idx)
565 hide_banner = 1;
566}
567
568static const AVOption *opt_find(void *obj, const char *name, const char *unit,
569 int opt_flags, int search_flags)
570{
571 const AVOption *o = av_opt_find(obj, name, unit, opt_flags, search_flags);
572 if(o && !o->flags)
573 return NULL;
574 return o;
575}
576
577#define FLAGS (o->type == AV_OPT_TYPE_FLAGS && (arg[0]=='-' || arg[0]=='+')) ? AV_DICT_APPEND : 0
578int opt_default(void *optctx, const char *opt, const char *arg)
579{
580 const AVOption *o;
581 int consumed = 0;
582 char opt_stripped[128];
583 const char *p;
584 const AVClass *cc = avcodec_get_class(), *fc = avformat_get_class();
585#if CONFIG_SWSCALE
586 const AVClass *sc = sws_get_class();
587#endif
588#if CONFIG_SWRESAMPLE
589 const AVClass *swr_class = swr_get_class();
590#endif
591
592 if (!strcmp(opt, "debug") || !strcmp(opt, "fdebug"))
593 av_log_set_level(AV_LOG_DEBUG);
594
595 if (!(p = strchr(opt, ':')))
596 p = opt + strlen(opt);
597 av_strlcpy(opt_stripped, opt, FFMIN(sizeof(opt_stripped), p - opt + 1));
598
599 if ((o = opt_find(&cc, opt_stripped, NULL, 0,
600 AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ)) ||
601 ((opt[0] == 'v' || opt[0] == 'a' || opt[0] == 's') &&
602 (o = opt_find(&cc, opt + 1, NULL, 0, AV_OPT_SEARCH_FAKE_OBJ)))) {
603 av_dict_set(&codec_opts, opt, arg, FLAGS);
604 consumed = 1;
605 }
606 if ((o = opt_find(&fc, opt, NULL, 0,
607 AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ))) {
608 av_dict_set(&format_opts, opt, arg, FLAGS);
609 if (consumed)
610 av_log(NULL, AV_LOG_VERBOSE, "Routing option %s to both codec and muxer layer\n", opt);
611 consumed = 1;
612 }
613#if CONFIG_SWSCALE
614 if (!consumed && (o = opt_find(&sc, opt, NULL, 0,
615 AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ))) {
616 struct SwsContext *sws = sws_alloc_context();
617 int ret = av_opt_set(sws, opt, arg, 0);
618 sws_freeContext(sws);
619 if (!strcmp(opt, "srcw") || !strcmp(opt, "srch") ||
620 !strcmp(opt, "dstw") || !strcmp(opt, "dsth") ||
621 !strcmp(opt, "src_format") || !strcmp(opt, "dst_format")) {
622 av_log(NULL, AV_LOG_ERROR, "Directly using swscale dimensions/format options is not supported, please use the -s or -pix_fmt options\n");
623 return AVERROR(EINVAL);
624 }
625 if (ret < 0) {
626 av_log(NULL, AV_LOG_ERROR, "Error setting option %s.\n", opt);
627 return ret;
628 }
629
630 av_dict_set(&sws_dict, opt, arg, FLAGS);
631
632 consumed = 1;
633 }
634#else
635 if (!consumed && !strcmp(opt, "sws_flags")) {
636 av_log(NULL, AV_LOG_WARNING, "Ignoring %s %s, due to disabled swscale\n", opt, arg);
637 consumed = 1;
638 }
639#endif
640#if CONFIG_SWRESAMPLE
641 if (!consumed && (o=opt_find(&swr_class, opt, NULL, 0,
642 AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ))) {
643 struct SwrContext *swr = swr_alloc();
644 int ret = av_opt_set(swr, opt, arg, 0);
645 swr_free(&swr);
646 if (ret < 0) {
647 av_log(NULL, AV_LOG_ERROR, "Error setting option %s.\n", opt);
648 return ret;
649 }
650 av_dict_set(&swr_opts, opt, arg, FLAGS);
651 consumed = 1;
652 }
653#endif
654
655 if (consumed)
656 return 0;
657 return AVERROR_OPTION_NOT_FOUND;
658}
659
660/*
661 * Check whether given option is a group separator.
662 *
663 * @return index of the group definition that matched or -1 if none
664 */
665static int match_group_separator(const OptionGroupDef *groups, int nb_groups,
666 const char *opt)
667{
668 int i;
669
670 for (i = 0; i < nb_groups; i++) {
671 const OptionGroupDef *p = &groups[i];
672 if (p->sep && !strcmp(p->sep, opt))
673 return i;
674 }
675
676 return -1;
677}
678
679/*
680 * Finish parsing an option group.
681 *
682 * @param group_idx which group definition should this group belong to
683 * @param arg argument of the group delimiting option
684 */
685static void finish_group(OptionParseContext *octx, int group_idx,
686 const char *arg)
687{
688 OptionGroupList *l = &octx->groups[group_idx];
689 OptionGroup *g;
690
692 g = &l->groups[l->nb_groups - 1];
693
694 *g = octx->cur_group;
695 g->arg = arg;
696 g->group_def = l->group_def;
697 g->sws_dict = sws_dict;
698 g->swr_opts = swr_opts;
702
703 codec_opts = NULL;
704 format_opts = NULL;
705 resample_opts = NULL;
706 sws_dict = NULL;
707 swr_opts = NULL;
708
709 memset(&octx->cur_group, 0, sizeof(octx->cur_group));
710}
711
712/*
713 * Add an option instance to currently parsed group.
714 */
715static void add_opt(OptionParseContext *octx, const OptionDef *opt,
716 const char *key, const char *val)
717{
718 int global = !(opt->flags & (OPT_PERFILE | OPT_SPEC | OPT_OFFSET));
719 OptionGroup *g = global ? &octx->global_opts : &octx->cur_group;
720
721 GROW_ARRAY(g->opts, g->nb_opts);
722 g->opts[g->nb_opts - 1].opt = opt;
723 g->opts[g->nb_opts - 1].key = key;
724 g->opts[g->nb_opts - 1].val = val;
725}
726
728 const OptionGroupDef *groups, int nb_groups)
729{
730 static const OptionGroupDef global_group = { "global" };
731 int i;
732
733 memset(octx, 0, sizeof(*octx));
734
735 octx->nb_groups = nb_groups;
736 octx->groups = av_mallocz_array(octx->nb_groups, sizeof(*octx->groups));
737 if (!octx->groups)
738 exit_program(1);
739
740 for (i = 0; i < octx->nb_groups; i++)
741 octx->groups[i].group_def = &groups[i];
742
743 octx->global_opts.group_def = &global_group;
744 octx->global_opts.arg = "";
745}
746
748{
749 int i, j;
750
751 for (i = 0; i < octx->nb_groups; i++) {
752 OptionGroupList *l = &octx->groups[i];
753
754 for (j = 0; j < l->nb_groups; j++) {
755 av_freep(&l->groups[j].opts);
756 av_dict_free(&l->groups[j].codec_opts);
757 av_dict_free(&l->groups[j].format_opts);
758 av_dict_free(&l->groups[j].resample_opts);
759
760 av_dict_free(&l->groups[j].sws_dict);
761 av_dict_free(&l->groups[j].swr_opts);
762 }
763 av_freep(&l->groups);
764 }
765 av_freep(&octx->groups);
766
767 av_freep(&octx->cur_group.opts);
768 av_freep(&octx->global_opts.opts);
769
770 uninit_opts();
771}
772
773int split_commandline(OptionParseContext *octx, int argc, char *argv[],
774 const OptionDef *options,
775 const OptionGroupDef *groups, int nb_groups)
776{
777 int optindex = 1;
778 int dashdash = -2;
779
780 /* perform system-dependent conversions for arguments list */
781 prepare_app_arguments(&argc, &argv);
782
783 init_parse_context(octx, groups, nb_groups);
784 av_log(NULL, AV_LOG_DEBUG, "Splitting the commandline.\n");
785
786 while (optindex < argc) {
787 const char *opt = argv[optindex++], *arg;
788 const OptionDef *po;
789 int ret;
790
791 av_log(NULL, AV_LOG_DEBUG, "Reading option '%s' ...", opt);
792
793 if (opt[0] == '-' && opt[1] == '-' && !opt[2]) {
794 dashdash = optindex;
795 continue;
796 }
797 /* unnamed group separators, e.g. output filename */
798 if (opt[0] != '-' || !opt[1] || dashdash+1 == optindex) {
799 finish_group(octx, 0, opt);
800 av_log(NULL, AV_LOG_DEBUG, " matched as %s.\n", groups[0].name);
801 continue;
802 }
803 opt++;
804
805#define GET_ARG(arg) \
806do { \
807 if (optindex < argc) { \
808 arg = argv[optindex++]; \
809 } else { \
810 av_log(NULL, AV_LOG_ERROR, "Missing argument for option '%s'.\n", opt);\
811 return AVERROR(EINVAL); \
812 } \
813} while (0)
814
815 /* named group separators, e.g. -i */
816 if ((ret = match_group_separator(groups, nb_groups, opt)) >= 0) {
817 GET_ARG(arg);
818 finish_group(octx, ret, arg);
819 av_log(NULL, AV_LOG_DEBUG, " matched as %s with argument '%s'.\n",
820 groups[ret].name, arg);
821 continue;
822 }
823
824 /* normal options */
825 po = find_option(options, opt);
826 if (po->name) {
827 if (po->flags & OPT_EXIT) {
828 /* optional argument, e.g. -h */
829 if (optindex < argc) {
830 arg = argv[optindex++];
831 } else {
832 arg = NULL;
833 }
834 } else if (po->flags & HAS_ARG) {
835 GET_ARG(arg);
836 } else {
837 arg = "1";
838 }
839
840 add_opt(octx, po, opt, arg);
841 av_log(NULL, AV_LOG_DEBUG, " matched as option '%s' (%s) with "
842 "argument '%s'.\n", po->name, po->help, arg);
843 continue;
844 }
845
846 /* AVOptions */
847 if ((optindex < argc) && argv[optindex]) {
848 ret = opt_default(NULL, opt, argv[optindex]);
849 if (ret >= 0) {
850 av_log(NULL, AV_LOG_DEBUG, " matched as AVOption '%s' with "
851 "argument '%s'.\n", opt, argv[optindex]);
852 optindex++;
853 continue;
854 } else if (ret != AVERROR_OPTION_NOT_FOUND) {
855 av_log(NULL, AV_LOG_ERROR, "Error parsing option '%s' "
856 "with argument '%s'.\n", opt, argv[optindex]);
857 return ret;
858 }
859 }
860
861 /* boolean -nofoo options */
862 if (opt[0] == 'n' && opt[1] == 'o' &&
863 (po = find_option(options, opt + 2)) &&
864 po->name && po->flags & OPT_BOOL) {
865 add_opt(octx, po, opt, "0");
866 av_log(NULL, AV_LOG_DEBUG, " matched as option '%s' (%s) with "
867 "argument 0.\n", po->name, po->help);
868 continue;
869 }
870
871 av_log(NULL, AV_LOG_ERROR, "Unrecognized option '%s'.\n", opt);
872 return AVERROR_OPTION_NOT_FOUND;
873 }
874
876 av_log(NULL, AV_LOG_WARNING, "Trailing option(s) found in the "
877 "command: may be ignored.\n");
878
879 av_log(NULL, AV_LOG_DEBUG, "Finished splitting the commandline.\n");
880
881 return 0;
882}
883
884int opt_cpuflags(void *optctx, const char *opt, const char *arg)
885{
886 int ret;
887 unsigned flags = av_get_cpu_flags();
888
889 if ((ret = av_parse_cpu_caps(&flags, arg)) < 0)
890 return ret;
891
892 av_force_cpu_flags(flags);
893 return 0;
894}
895
896int opt_cpucount(void *optctx, const char *opt, const char *arg)
897{
898 int ret;
899 int count;
900
901 static const AVOption opts[] = {
902 {"count", NULL, 0, AV_OPT_TYPE_INT, { .i64 = -1}, -1, INT_MAX, 0},
903 {NULL},
904 };
905 static const AVClass class = {
906 .class_name = "cpucount",
907 .item_name = av_default_item_name,
908 .option = opts,
909 .version = LIBAVUTIL_VERSION_INT,
910 };
911 const AVClass *pclass = &class;
912
913 ret = av_opt_eval_int(&pclass, opts, arg, &count);
914
915 if (!ret) {
916 av_cpu_force_count(count);
917 }
918
919 return ret;
920}
921
922int opt_loglevel(void *optctx, const char *opt, const char *arg)
923{
924 const struct { const char *name; int level; } log_levels[] = {
925 { "quiet" , AV_LOG_QUIET },
926 { "panic" , AV_LOG_PANIC },
927 { "fatal" , AV_LOG_FATAL },
928 { "error" , AV_LOG_ERROR },
929 { "warning", AV_LOG_WARNING },
930 { "info" , AV_LOG_INFO },
931 { "verbose", AV_LOG_VERBOSE },
932 { "debug" , AV_LOG_DEBUG },
933 { "trace" , AV_LOG_TRACE },
934 };
935 const char *token;
936 char *tail;
937 int flags = av_log_get_flags();
938 int level = av_log_get_level();
939 int cmd, i = 0;
940
941 av_assert0(arg);
942 while (*arg) {
943 token = arg;
944 if (*token == '+' || *token == '-') {
945 cmd = *token++;
946 } else {
947 cmd = 0;
948 }
949 if (!i && !cmd) {
950 flags = 0; /* missing relative prefix, build absolute value */
951 }
952 if (av_strstart(token, "repeat", &arg)) {
953 if (cmd == '-') {
954 flags |= AV_LOG_SKIP_REPEATED;
955 } else {
956 flags &= ~AV_LOG_SKIP_REPEATED;
957 }
958 } else if (av_strstart(token, "level", &arg)) {
959 if (cmd == '-') {
960 flags &= ~AV_LOG_PRINT_LEVEL;
961 } else {
962 flags |= AV_LOG_PRINT_LEVEL;
963 }
964 } else {
965 break;
966 }
967 i++;
968 }
969 if (!*arg) {
970 goto end;
971 } else if (*arg == '+') {
972 arg++;
973 } else if (!i) {
974 flags = av_log_get_flags(); /* level value without prefix, reset flags */
975 }
976
977 for (i = 0; i < FF_ARRAY_ELEMS(log_levels); i++) {
978 if (!strcmp(log_levels[i].name, arg)) {
979 level = log_levels[i].level;
980 goto end;
981 }
982 }
983
984 level = strtol(arg, &tail, 10);
985 if (*tail) {
986 av_log(NULL, AV_LOG_FATAL, "Invalid loglevel \"%s\". "
987 "Possible levels are numbers or:\n", arg);
988 for (i = 0; i < FF_ARRAY_ELEMS(log_levels); i++)
989 av_log(NULL, AV_LOG_FATAL, "\"%s\"\n", log_levels[i].name);
990 exit_program(1);
991 }
992
993end:
994 av_log_set_flags(flags);
995 av_log_set_level(level);
996 return 0;
997}
998
999static void expand_filename_template(AVBPrint *bp, const char *template,
1000 struct tm *tm)
1001{
1002 int c;
1003
1004 while ((c = *(template++))) {
1005 if (c == '%') {
1006 if (!(c = *(template++)))
1007 break;
1008 switch (c) {
1009 case 'p':
1010 av_bprintf(bp, "%s", program_name);
1011 break;
1012 case 't':
1013 av_bprintf(bp, "%04d%02d%02d-%02d%02d%02d",
1014 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
1015 tm->tm_hour, tm->tm_min, tm->tm_sec);
1016 break;
1017 case '%':
1018 av_bprint_chars(bp, c, 1);
1019 break;
1020 }
1021 } else {
1022 av_bprint_chars(bp, c, 1);
1023 }
1024 }
1025}
1026
1027static int init_report(const char *env)
1028{
1029 char *filename_template = NULL;
1030 char *key, *val;
1031 int ret, count = 0;
1032 int prog_loglevel, envlevel = 0;
1033 time_t now;
1034 struct tm *tm;
1035 AVBPrint filename;
1036
1037 if (report_file) /* already opened */
1038 return 0;
1039 time(&now);
1040 tm = localtime(&now);
1041
1042 while (env && *env) {
1043 if ((ret = av_opt_get_key_value(&env, "=", ":", 0, &key, &val)) < 0) {
1044 if (count)
1045 av_log(NULL, AV_LOG_ERROR,
1046 "Failed to parse FFREPORT environment variable: %s\n",
1047 av_err2str(ret));
1048 break;
1049 }
1050 if (*env)
1051 env++;
1052 count++;
1053 if (!strcmp(key, "file")) {
1054 av_free(filename_template);
1055 filename_template = val;
1056 val = NULL;
1057 } else if (!strcmp(key, "level")) {
1058 char *tail;
1059 report_file_level = strtol(val, &tail, 10);
1060 if (*tail) {
1061 av_log(NULL, AV_LOG_FATAL, "Invalid report file level\n");
1062 exit_program(1);
1063 }
1064 envlevel = 1;
1065 } else {
1066 av_log(NULL, AV_LOG_ERROR, "Unknown key '%s' in FFREPORT\n", key);
1067 }
1068 av_free(val);
1069 av_free(key);
1070 }
1071
1072 av_bprint_init(&filename, 0, AV_BPRINT_SIZE_AUTOMATIC);
1073 expand_filename_template(&filename,
1074 av_x_if_null(filename_template, "%p-%t.log"), tm);
1075 av_free(filename_template);
1076 if (!av_bprint_is_complete(&filename)) {
1077 av_log(NULL, AV_LOG_ERROR, "Out of memory building report file name\n");
1078 return AVERROR(ENOMEM);
1079 }
1080
1081 prog_loglevel = av_log_get_level();
1082 if (!envlevel)
1083 report_file_level = FFMAX(report_file_level, prog_loglevel);
1084
1085 report_file = fopen(filename.str, "w");
1086 if (!report_file) {
1087 int ret = AVERROR(errno);
1088 av_log(NULL, AV_LOG_ERROR, "Failed to open report \"%s\": %s\n",
1089 filename.str, strerror(errno));
1090 return ret;
1091 }
1092 av_log_set_callback(log_callback_report);
1093 av_log(NULL, AV_LOG_INFO,
1094 "%s started on %04d-%02d-%02d at %02d:%02d:%02d\n"
1095 "Report written to \"%s\"\n"
1096 "Log level: %d\n",
1098 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
1099 tm->tm_hour, tm->tm_min, tm->tm_sec,
1100 filename.str, report_file_level);
1101 av_bprint_finalize(&filename, NULL);
1102 return 0;
1103}
1104
1105int opt_report(void *optctx, const char *opt, const char *arg)
1106{
1107 return init_report(NULL);
1108}
1109
1110int opt_max_alloc(void *optctx, const char *opt, const char *arg)
1111{
1112 char *tail;
1113 size_t max;
1114
1115 max = strtol(arg, &tail, 10);
1116 if (*tail) {
1117 av_log(NULL, AV_LOG_FATAL, "Invalid max_alloc \"%s\".\n", arg);
1118 exit_program(1);
1119 }
1120 av_max_alloc(max);
1121 return 0;
1122}
1123
1124int opt_timelimit(void *optctx, const char *opt, const char *arg)
1125{
1126#if HAVE_SETRLIMIT
1127 int lim = parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX);
1128 struct rlimit rl = { lim, lim + 1 };
1129 if (setrlimit(RLIMIT_CPU, &rl))
1130 perror("setrlimit");
1131#else
1132 av_log(NULL, AV_LOG_WARNING, "-%s not implemented on this OS\n", opt);
1133#endif
1134 return 0;
1135}
1136
1137void print_error(const char *filename, int err)
1138{
1139 char errbuf[128];
1140 const char *errbuf_ptr = errbuf;
1141
1142 if (av_strerror(err, errbuf, sizeof(errbuf)) < 0)
1143 errbuf_ptr = strerror(AVUNERROR(err));
1144 av_log(NULL, AV_LOG_ERROR, "%s: %s\n", filename, errbuf_ptr);
1145}
1146
1147__thread int warned_cfg = 0;
1148
1149#define INDENT 1
1150#define SHOW_VERSION 2
1151#define SHOW_CONFIG 4
1152#define SHOW_COPYRIGHT 8
1153
1154#define PRINT_LIB_INFO(libname, LIBNAME, flags, level) \
1155 if (CONFIG_##LIBNAME) { \
1156 const char *indent = flags & INDENT? " " : ""; \
1157 if (flags & SHOW_VERSION) { \
1158 unsigned int version = libname##_version(); \
1159 av_log(NULL, level, \
1160 "%slib%-11s %2d.%3d.%3d / %2d.%3d.%3d\n", \
1161 indent, #libname, \
1162 LIB##LIBNAME##_VERSION_MAJOR, \
1163 LIB##LIBNAME##_VERSION_MINOR, \
1164 LIB##LIBNAME##_VERSION_MICRO, \
1165 AV_VERSION_MAJOR(version), AV_VERSION_MINOR(version),\
1166 AV_VERSION_MICRO(version)); \
1167 } \
1168 if (flags & SHOW_CONFIG) { \
1169 const char *cfg = libname##_configuration(); \
1170 if (strcmp(FFMPEG_CONFIGURATION, cfg)) { \
1171 if (!warned_cfg) { \
1172 av_log(NULL, level, \
1173 "%sWARNING: library configuration mismatch\n", \
1174 indent); \
1175 warned_cfg = 1; \
1176 } \
1177 av_log(NULL, level, "%s%-11s configuration: %s\n", \
1178 indent, #libname, cfg); \
1179 } \
1180 } \
1181 } \
1182
1183static void print_all_libs_info(int flags, int level)
1184{
1185 PRINT_LIB_INFO(avutil, AVUTIL, flags, level);
1186 PRINT_LIB_INFO(avcodec, AVCODEC, flags, level);
1187 PRINT_LIB_INFO(avformat, AVFORMAT, flags, level);
1188 PRINT_LIB_INFO(avdevice, AVDEVICE, flags, level);
1189 PRINT_LIB_INFO(avfilter, AVFILTER, flags, level);
1190 PRINT_LIB_INFO(swscale, SWSCALE, flags, level);
1191 PRINT_LIB_INFO(swresample, SWRESAMPLE, flags, level);
1192}
1193
1194static void print_program_info(int flags, int level)
1195{
1196 const char *indent = flags & INDENT? " " : "";
1197
1198 av_log(NULL, level, "%s version " FFMPEG_VERSION, program_name);
1199 if (flags & SHOW_COPYRIGHT)
1200 av_log(NULL, level, " Copyright (c) %d-%d the FFmpeg developers",
1201 program_birth_year, CONFIG_THIS_YEAR);
1202 av_log(NULL, level, "\n");
1203 av_log(NULL, level, "%sbuilt with %s\n", indent, CC_IDENT);
1204
1205 av_log(NULL, level, "%sconfiguration: " FFMPEG_CONFIGURATION "\n", indent);
1206}
1207
1208static void print_buildconf(int flags, int level)
1209{
1210 const char *indent = flags & INDENT ? " " : "";
1211 char str[] = { FFMPEG_CONFIGURATION };
1212 char *conflist, *remove_tilde, *splitconf;
1213
1214 // Change all the ' --' strings to '~--' so that
1215 // they can be identified as tokens.
1216 while ((conflist = strstr(str, " --")) != NULL) {
1217 conflist[0] = '~';
1218 }
1219
1220 // Compensate for the weirdness this would cause
1221 // when passing 'pkg-config --static'.
1222 while ((remove_tilde = strstr(str, "pkg-config~")) != NULL) {
1223 remove_tilde[sizeof("pkg-config~") - 2] = ' ';
1224 }
1225
1226 splitconf = strtok(str, "~");
1227 av_log(NULL, level, "\n%sconfiguration:\n", indent);
1228 while (splitconf != NULL) {
1229 av_log(NULL, level, "%s%s%s\n", indent, indent, splitconf);
1230 splitconf = strtok(NULL, "~");
1231 }
1232}
1233
1234void show_banner(int argc, char **argv, const OptionDef *options)
1235{
1236 int idx = locate_option(argc, argv, options, "version");
1237 if (hide_banner || idx)
1238 return;
1239
1243}
1244
1245int show_version(void *optctx, const char *opt, const char *arg)
1246{
1247 print_program_info (SHOW_COPYRIGHT, AV_LOG_INFO);
1248 print_all_libs_info(SHOW_VERSION, AV_LOG_INFO);
1249
1250 return 0;
1251}
1252
1253int show_buildconf(void *optctx, const char *opt, const char *arg)
1254{
1255 print_buildconf (INDENT|0, AV_LOG_INFO);
1256
1257 return 0;
1258}
1259
1260int show_license(void *optctx, const char *opt, const char *arg)
1261{
1262#if CONFIG_NONFREE
1263 av_log(NULL, AV_LOG_STDERR,
1264 "This version of %s has nonfree parts compiled in.\n"
1265 "Therefore it is not legally redistributable.\n",
1266 program_name );
1267#elif CONFIG_GPLV3
1268 av_log(NULL, AV_LOG_STDERR,
1269 "%s is free software; you can redistribute it and/or modify\n"
1270 "it under the terms of the GNU General Public License as published by\n"
1271 "the Free Software Foundation; either version 3 of the License, or\n"
1272 "(at your option) any later version.\n"
1273 "\n"
1274 "%s is distributed in the hope that it will be useful,\n"
1275 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
1276 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
1277 "GNU General Public License for more details.\n"
1278 "\n"
1279 "You should have received a copy of the GNU General Public License\n"
1280 "along with %s. If not, see <http://www.gnu.org/licenses/>.\n",
1282#elif CONFIG_GPL
1283 av_log(NULL, AV_LOG_STDERR,
1284 "%s is free software; you can redistribute it and/or modify\n"
1285 "it under the terms of the GNU General Public License as published by\n"
1286 "the Free Software Foundation; either version 2 of the License, or\n"
1287 "(at your option) any later version.\n"
1288 "\n"
1289 "%s is distributed in the hope that it will be useful,\n"
1290 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
1291 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
1292 "GNU General Public License for more details.\n"
1293 "\n"
1294 "You should have received a copy of the GNU General Public License\n"
1295 "along with %s; if not, write to the Free Software\n"
1296 "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n",
1298#elif CONFIG_LGPLV3
1299 av_log(NULL, AV_LOG_STDERR,
1300 "%s is free software; you can redistribute it and/or modify\n"
1301 "it under the terms of the GNU Lesser General Public License as published by\n"
1302 "the Free Software Foundation; either version 3 of the License, or\n"
1303 "(at your option) any later version.\n"
1304 "\n"
1305 "%s is distributed in the hope that it will be useful,\n"
1306 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
1307 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
1308 "GNU Lesser General Public License for more details.\n"
1309 "\n"
1310 "You should have received a copy of the GNU Lesser General Public License\n"
1311 "along with %s. If not, see <http://www.gnu.org/licenses/>.\n",
1313#else
1314 av_log(NULL, AV_LOG_STDERR,
1315 "%s is free software; you can redistribute it and/or\n"
1316 "modify it under the terms of the GNU Lesser General Public\n"
1317 "License as published by the Free Software Foundation; either\n"
1318 "version 2.1 of the License, or (at your option) any later version.\n"
1319 "\n"
1320 "%s is distributed in the hope that it will be useful,\n"
1321 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
1322 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n"
1323 "Lesser General Public License for more details.\n"
1324 "\n"
1325 "You should have received a copy of the GNU Lesser General Public\n"
1326 "License along with %s; if not, write to the Free Software\n"
1327 "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n",
1329#endif
1330
1331 return 0;
1332}
1333
1334static int is_device(const AVClass *avclass)
1335{
1336 if (!avclass)
1337 return 0;
1338 return AV_IS_INPUT_DEVICE(avclass->category) || AV_IS_OUTPUT_DEVICE(avclass->category);
1339}
1340
1341static int show_formats_devices(void *optctx, const char *opt, const char *arg, int device_only, int muxdemuxers)
1342{
1343 void *ifmt_opaque = NULL;
1344 const AVInputFormat *ifmt = NULL;
1345 void *ofmt_opaque = NULL;
1346 const AVOutputFormat *ofmt = NULL;
1347 const char *last_name;
1348 int is_dev;
1349
1350 av_log(NULL, AV_LOG_STDERR, "%s\n"
1351 " D. = Demuxing supported\n"
1352 " .E = Muxing supported\n"
1353 " --\n", device_only ? "Devices:" : "File formats:");
1354 last_name = "000";
1355 for (;;) {
1356 int decode = 0;
1357 int encode = 0;
1358 const char *name = NULL;
1359 const char *long_name = NULL;
1360
1361 if (muxdemuxers !=SHOW_DEMUXERS) {
1362 ofmt_opaque = NULL;
1363 while ((ofmt = av_muxer_iterate(&ofmt_opaque))) {
1364 is_dev = is_device(ofmt->priv_class);
1365 if (!is_dev && device_only)
1366 continue;
1367 if ((!name || strcmp(ofmt->name, name) < 0) &&
1368 strcmp(ofmt->name, last_name) > 0) {
1369 name = ofmt->name;
1370 long_name = ofmt->long_name;
1371 encode = 1;
1372 }
1373 }
1374 }
1375 if (muxdemuxers != SHOW_MUXERS) {
1376 ifmt_opaque = NULL;
1377 while ((ifmt = av_demuxer_iterate(&ifmt_opaque))) {
1378 is_dev = is_device(ifmt->priv_class);
1379 if (!is_dev && device_only)
1380 continue;
1381 if ((!name || strcmp(ifmt->name, name) < 0) &&
1382 strcmp(ifmt->name, last_name) > 0) {
1383 name = ifmt->name;
1384 long_name = ifmt->long_name;
1385 encode = 0;
1386 }
1387 if (name && strcmp(ifmt->name, name) == 0)
1388 decode = 1;
1389 }
1390 }
1391 if (!name)
1392 break;
1393 last_name = name;
1394
1395 av_log(NULL, AV_LOG_STDERR, " %s%s %-15s %s\n",
1396 decode ? "D" : " ",
1397 encode ? "E" : " ",
1398 name,
1399 long_name ? long_name:" ");
1400 }
1401 return 0;
1402}
1403
1404int show_formats(void *optctx, const char *opt, const char *arg)
1405{
1406 return show_formats_devices(optctx, opt, arg, 0, SHOW_DEFAULT);
1407}
1408
1409int show_muxers(void *optctx, const char *opt, const char *arg)
1410{
1411 return show_formats_devices(optctx, opt, arg, 0, SHOW_MUXERS);
1412}
1413
1414int show_demuxers(void *optctx, const char *opt, const char *arg)
1415{
1416 return show_formats_devices(optctx, opt, arg, 0, SHOW_DEMUXERS);
1417}
1418
1419int show_devices(void *optctx, const char *opt, const char *arg)
1420{
1421 return show_formats_devices(optctx, opt, arg, 1, SHOW_DEFAULT);
1422}
1423
1424#define PRINT_CODEC_SUPPORTED(codec, field, type, list_name, term, get_name) \
1425 if (codec->field) { \
1426 const type *p = codec->field; \
1427 \
1428 av_log(NULL, AV_LOG_STDERR, " Supported " list_name ":"); \
1429 while (*p != term) { \
1430 get_name(*p); \
1431 av_log(NULL, AV_LOG_STDERR, " %s", name); \
1432 p++; \
1433 } \
1434 av_log(NULL, AV_LOG_STDERR, "\n"); \
1435 } \
1436
1437static void print_codec(const AVCodec *c)
1438{
1439 int encoder = av_codec_is_encoder(c);
1440
1441 av_log(NULL, AV_LOG_STDERR, "%s %s [%s]:\n", encoder ? "Encoder" : "Decoder", c->name,
1442 c->long_name ? c->long_name : "");
1443
1444 av_log(NULL, AV_LOG_STDERR, " General capabilities: ");
1445 if (c->capabilities & AV_CODEC_CAP_DRAW_HORIZ_BAND)
1446 av_log(NULL, AV_LOG_STDERR, "horizband ");
1447 if (c->capabilities & AV_CODEC_CAP_DR1)
1448 av_log(NULL, AV_LOG_STDERR, "dr1 ");
1449 if (c->capabilities & AV_CODEC_CAP_TRUNCATED)
1450 av_log(NULL, AV_LOG_STDERR, "trunc ");
1451 if (c->capabilities & AV_CODEC_CAP_DELAY)
1452 av_log(NULL, AV_LOG_STDERR, "delay ");
1453 if (c->capabilities & AV_CODEC_CAP_SMALL_LAST_FRAME)
1454 av_log(NULL, AV_LOG_STDERR, "small ");
1455 if (c->capabilities & AV_CODEC_CAP_SUBFRAMES)
1456 av_log(NULL, AV_LOG_STDERR, "subframes ");
1457 if (c->capabilities & AV_CODEC_CAP_EXPERIMENTAL)
1458 av_log(NULL, AV_LOG_STDERR, "exp ");
1459 if (c->capabilities & AV_CODEC_CAP_CHANNEL_CONF)
1460 av_log(NULL, AV_LOG_STDERR, "chconf ");
1461 if (c->capabilities & AV_CODEC_CAP_PARAM_CHANGE)
1462 av_log(NULL, AV_LOG_STDERR, "paramchange ");
1463 if (c->capabilities & AV_CODEC_CAP_VARIABLE_FRAME_SIZE)
1464 av_log(NULL, AV_LOG_STDERR, "variable ");
1465 if (c->capabilities & (AV_CODEC_CAP_FRAME_THREADS |
1466 AV_CODEC_CAP_SLICE_THREADS |
1467 AV_CODEC_CAP_OTHER_THREADS))
1468 av_log(NULL, AV_LOG_STDERR, "threads ");
1469 if (c->capabilities & AV_CODEC_CAP_AVOID_PROBING)
1470 av_log(NULL, AV_LOG_STDERR, "avoidprobe ");
1471 if (c->capabilities & AV_CODEC_CAP_HARDWARE)
1472 av_log(NULL, AV_LOG_STDERR, "hardware ");
1473 if (c->capabilities & AV_CODEC_CAP_HYBRID)
1474 av_log(NULL, AV_LOG_STDERR, "hybrid ");
1475 if (!c->capabilities)
1476 av_log(NULL, AV_LOG_STDERR, "none");
1477 av_log(NULL, AV_LOG_STDERR, "\n");
1478
1479 if (c->type == AVMEDIA_TYPE_VIDEO ||
1480 c->type == AVMEDIA_TYPE_AUDIO) {
1481 av_log(NULL, AV_LOG_STDERR, " Threading capabilities: ");
1482 switch (c->capabilities & (AV_CODEC_CAP_FRAME_THREADS |
1483 AV_CODEC_CAP_SLICE_THREADS |
1484 AV_CODEC_CAP_OTHER_THREADS)) {
1485 case AV_CODEC_CAP_FRAME_THREADS |
1486 AV_CODEC_CAP_SLICE_THREADS: av_log(NULL, AV_LOG_STDERR, "frame and slice"); break;
1487 case AV_CODEC_CAP_FRAME_THREADS: av_log(NULL, AV_LOG_STDERR, "frame"); break;
1488 case AV_CODEC_CAP_SLICE_THREADS: av_log(NULL, AV_LOG_STDERR, "slice"); break;
1489 case AV_CODEC_CAP_OTHER_THREADS : av_log(NULL, AV_LOG_STDERR, "other"); break;
1490 default: av_log(NULL, AV_LOG_STDERR, "none"); break;
1491 }
1492 av_log(NULL, AV_LOG_STDERR, "\n");
1493 }
1494
1495 if (avcodec_get_hw_config(c, 0)) {
1496 av_log(NULL, AV_LOG_STDERR, " Supported hardware devices: ");
1497 for (int i = 0;; i++) {
1498 const AVCodecHWConfig *config = avcodec_get_hw_config(c, i);
1499 if (!config)
1500 break;
1501 av_log(NULL, AV_LOG_STDERR, "%s ", av_hwdevice_get_type_name(config->device_type));
1502 }
1503 av_log(NULL, AV_LOG_STDERR, "\n");
1504 }
1505
1506 if (c->supported_framerates) {
1507 const AVRational *fps = c->supported_framerates;
1508
1509 av_log(NULL, AV_LOG_STDERR, " Supported framerates:");
1510 while (fps->num) {
1511 av_log(NULL, AV_LOG_STDERR, " %d/%d", fps->num, fps->den);
1512 fps++;
1513 }
1514 av_log(NULL, AV_LOG_STDERR, "\n");
1515 }
1516 PRINT_CODEC_SUPPORTED(c, pix_fmts, enum AVPixelFormat, "pixel formats",
1517 AV_PIX_FMT_NONE, GET_PIX_FMT_NAME);
1518 PRINT_CODEC_SUPPORTED(c, supported_samplerates, int, "sample rates", 0,
1520 PRINT_CODEC_SUPPORTED(c, sample_fmts, enum AVSampleFormat, "sample formats",
1521 AV_SAMPLE_FMT_NONE, GET_SAMPLE_FMT_NAME);
1522 PRINT_CODEC_SUPPORTED(c, channel_layouts, uint64_t, "channel layouts",
1524
1525 if (c->priv_class) {
1526 show_help_children(c->priv_class,
1527 AV_OPT_FLAG_ENCODING_PARAM |
1528 AV_OPT_FLAG_DECODING_PARAM);
1529 }
1530}
1531
1532static char get_media_type_char(enum AVMediaType type)
1533{
1534 switch (type) {
1535 case AVMEDIA_TYPE_VIDEO: return 'V';
1536 case AVMEDIA_TYPE_AUDIO: return 'A';
1537 case AVMEDIA_TYPE_DATA: return 'D';
1538 case AVMEDIA_TYPE_SUBTITLE: return 'S';
1539 case AVMEDIA_TYPE_ATTACHMENT:return 'T';
1540 default: return '?';
1541 }
1542}
1543
1544static const AVCodec *next_codec_for_id(enum AVCodecID id, void **iter,
1545 int encoder)
1546{
1547 const AVCodec *c;
1548 while ((c = av_codec_iterate(iter))) {
1549 if (c->id == id &&
1550 (encoder ? av_codec_is_encoder(c) : av_codec_is_decoder(c)))
1551 return c;
1552 }
1553 return NULL;
1554}
1555
1556static int compare_codec_desc(const void *a, const void *b)
1557{
1558 const AVCodecDescriptor * const *da = a;
1559 const AVCodecDescriptor * const *db = b;
1560
1561 return (*da)->type != (*db)->type ? FFDIFFSIGN((*da)->type, (*db)->type) :
1562 strcmp((*da)->name, (*db)->name);
1563}
1564
1565static unsigned get_codecs_sorted(const AVCodecDescriptor ***rcodecs)
1566{
1567 const AVCodecDescriptor *desc = NULL;
1568 const AVCodecDescriptor **codecs;
1569 unsigned nb_codecs = 0, i = 0;
1570
1571 while ((desc = avcodec_descriptor_next(desc)))
1572 nb_codecs++;
1573 if (!(codecs = av_calloc(nb_codecs, sizeof(*codecs)))) {
1574 av_log(NULL, AV_LOG_ERROR, "Out of memory\n");
1575 exit_program(1);
1576 }
1577 desc = NULL;
1578 while ((desc = avcodec_descriptor_next(desc)))
1579 codecs[i++] = desc;
1580 av_assert0(i == nb_codecs);
1581 qsort(codecs, nb_codecs, sizeof(*codecs), compare_codec_desc);
1582 *rcodecs = codecs;
1583 return nb_codecs;
1584}
1585
1586static void print_codecs_for_id(enum AVCodecID id, int encoder)
1587{
1588 void *iter = NULL;
1589 const AVCodec *codec;
1590
1591 av_log(NULL, AV_LOG_STDERR, " (%s: ", encoder ? "encoders" : "decoders");
1592
1593 while ((codec = next_codec_for_id(id, &iter, encoder)))
1594 av_log(NULL, AV_LOG_STDERR, "%s ", codec->name);
1595
1596 av_log(NULL, AV_LOG_STDERR, ")");
1597}
1598
1599int show_codecs(void *optctx, const char *opt, const char *arg)
1600{
1601 const AVCodecDescriptor **codecs;
1602 unsigned i, nb_codecs = get_codecs_sorted(&codecs);
1603
1604 av_log(NULL, AV_LOG_STDERR, "Codecs:\n"
1605 " D..... = Decoding supported\n"
1606 " .E.... = Encoding supported\n"
1607 " ..V... = Video codec\n"
1608 " ..A... = Audio codec\n"
1609 " ..S... = Subtitle codec\n"
1610 " ...I.. = Intra frame-only codec\n"
1611 " ....L. = Lossy compression\n"
1612 " .....S = Lossless compression\n"
1613 " -------\n");
1614 for (i = 0; i < nb_codecs; i++) {
1615 const AVCodecDescriptor *desc = codecs[i];
1616 const AVCodec *codec;
1617 void *iter = NULL;
1618
1619 if (strstr(desc->name, "_deprecated"))
1620 continue;
1621
1622 av_log(NULL, AV_LOG_STDERR, " ");
1623 av_log(NULL, AV_LOG_STDERR, avcodec_find_decoder(desc->id) ? "D" : ".");
1624 av_log(NULL, AV_LOG_STDERR, avcodec_find_encoder(desc->id) ? "E" : ".");
1625
1626 av_log(NULL, AV_LOG_STDERR, "%c", get_media_type_char(desc->type));
1627 av_log(NULL, AV_LOG_STDERR, (desc->props & AV_CODEC_PROP_INTRA_ONLY) ? "I" : ".");
1628 av_log(NULL, AV_LOG_STDERR, (desc->props & AV_CODEC_PROP_LOSSY) ? "L" : ".");
1629 av_log(NULL, AV_LOG_STDERR, (desc->props & AV_CODEC_PROP_LOSSLESS) ? "S" : ".");
1630
1631 av_log(NULL, AV_LOG_STDERR, " %-20s %s", desc->name, desc->long_name ? desc->long_name : "");
1632
1633 /* print decoders/encoders when there's more than one or their
1634 * names are different from codec name */
1635 while ((codec = next_codec_for_id(desc->id, &iter, 0))) {
1636 if (strcmp(codec->name, desc->name)) {
1637 print_codecs_for_id(desc->id, 0);
1638 break;
1639 }
1640 }
1641 iter = NULL;
1642 while ((codec = next_codec_for_id(desc->id, &iter, 1))) {
1643 if (strcmp(codec->name, desc->name)) {
1644 print_codecs_for_id(desc->id, 1);
1645 break;
1646 }
1647 }
1648
1649 av_log(NULL, AV_LOG_STDERR, "\n");
1650 }
1651 av_free(codecs);
1652 return 0;
1653}
1654
1655static void print_codecs(int encoder)
1656{
1657 const AVCodecDescriptor **codecs;
1658 unsigned i, nb_codecs = get_codecs_sorted(&codecs);
1659
1660 av_log(NULL, AV_LOG_STDERR, "%s:\n"
1661 " V..... = Video\n"
1662 " A..... = Audio\n"
1663 " S..... = Subtitle\n"
1664 " .F.... = Frame-level multithreading\n"
1665 " ..S... = Slice-level multithreading\n"
1666 " ...X.. = Codec is experimental\n"
1667 " ....B. = Supports draw_horiz_band\n"
1668 " .....D = Supports direct rendering method 1\n"
1669 " ------\n",
1670 encoder ? "Encoders" : "Decoders");
1671 for (i = 0; i < nb_codecs; i++) {
1672 const AVCodecDescriptor *desc = codecs[i];
1673 const AVCodec *codec;
1674 void *iter = NULL;
1675
1676 while ((codec = next_codec_for_id(desc->id, &iter, encoder))) {
1677 av_log(NULL, AV_LOG_STDERR, " %c", get_media_type_char(desc->type));
1678 av_log(NULL, AV_LOG_STDERR, (codec->capabilities & AV_CODEC_CAP_FRAME_THREADS) ? "F" : ".");
1679 av_log(NULL, AV_LOG_STDERR, (codec->capabilities & AV_CODEC_CAP_SLICE_THREADS) ? "S" : ".");
1680 av_log(NULL, AV_LOG_STDERR, (codec->capabilities & AV_CODEC_CAP_EXPERIMENTAL) ? "X" : ".");
1681 av_log(NULL, AV_LOG_STDERR, (codec->capabilities & AV_CODEC_CAP_DRAW_HORIZ_BAND)?"B" : ".");
1682 av_log(NULL, AV_LOG_STDERR, (codec->capabilities & AV_CODEC_CAP_DR1) ? "D" : ".");
1683
1684 av_log(NULL, AV_LOG_STDERR, " %-20s %s", codec->name, codec->long_name ? codec->long_name : "");
1685 if (strcmp(codec->name, desc->name))
1686 av_log(NULL, AV_LOG_STDERR, " (codec %s)", desc->name);
1687
1688 av_log(NULL, AV_LOG_STDERR, "\n");
1689 }
1690 }
1691 av_free(codecs);
1692}
1693
1694int show_decoders(void *optctx, const char *opt, const char *arg)
1695{
1696 print_codecs(0);
1697 return 0;
1698}
1699
1700int show_encoders(void *optctx, const char *opt, const char *arg)
1701{
1702 print_codecs(1);
1703 return 0;
1704}
1705
1706int show_bsfs(void *optctx, const char *opt, const char *arg)
1707{
1708 const AVBitStreamFilter *bsf = NULL;
1709 void *opaque = NULL;
1710
1711 av_log(NULL, AV_LOG_STDERR, "Bitstream filters:\n");
1712 while ((bsf = av_bsf_iterate(&opaque)))
1713 av_log(NULL, AV_LOG_STDERR, "%s\n", bsf->name);
1714 av_log(NULL, AV_LOG_STDERR, "\n");
1715 return 0;
1716}
1717
1718int show_protocols(void *optctx, const char *opt, const char *arg)
1719{
1720 void *opaque = NULL;
1721 const char *name;
1722
1723 av_log(NULL, AV_LOG_STDERR, "Supported file protocols:\n"
1724 "Input:\n");
1725 while ((name = avio_enum_protocols(&opaque, 0)))
1726 av_log(NULL, AV_LOG_STDERR, " %s\n", name);
1727 av_log(NULL, AV_LOG_STDERR, "Output:\n");
1728 while ((name = avio_enum_protocols(&opaque, 1)))
1729 av_log(NULL, AV_LOG_STDERR, " %s\n", name);
1730 return 0;
1731}
1732
1733int show_filters(void *optctx, const char *opt, const char *arg)
1734{
1735#if CONFIG_AVFILTER
1736 const AVFilter *filter = NULL;
1737 char descr[64], *descr_cur;
1738 void *opaque = NULL;
1739 int i, j;
1740 const AVFilterPad *pad;
1741
1742 av_log(NULL, AV_LOG_STDERR, "Filters:\n"
1743 " T.. = Timeline support\n"
1744 " .S. = Slice threading\n"
1745 " ..C = Command support\n"
1746 " A = Audio input/output\n"
1747 " V = Video input/output\n"
1748 " N = Dynamic number and/or type of input/output\n"
1749 " | = Source or sink filter\n");
1750 while ((filter = av_filter_iterate(&opaque))) {
1751 descr_cur = descr;
1752 for (i = 0; i < 2; i++) {
1753 if (i) {
1754 *(descr_cur++) = '-';
1755 *(descr_cur++) = '>';
1756 }
1757 pad = i ? filter->outputs : filter->inputs;
1758 for (j = 0; pad && avfilter_pad_get_name(pad, j); j++) {
1759 if (descr_cur >= descr + sizeof(descr) - 4)
1760 break;
1761 *(descr_cur++) = get_media_type_char(avfilter_pad_get_type(pad, j));
1762 }
1763 if (!j)
1764 *(descr_cur++) = ((!i && (filter->flags & AVFILTER_FLAG_DYNAMIC_INPUTS)) ||
1765 ( i && (filter->flags & AVFILTER_FLAG_DYNAMIC_OUTPUTS))) ? 'N' : '|';
1766 }
1767 *descr_cur = 0;
1768 av_log(NULL, AV_LOG_STDERR, " %c%c%c %-17s %-10s %s\n",
1769 filter->flags & AVFILTER_FLAG_SUPPORT_TIMELINE ? 'T' : '.',
1770 filter->flags & AVFILTER_FLAG_SLICE_THREADS ? 'S' : '.',
1771 filter->process_command ? 'C' : '.',
1772 filter->name, descr, filter->description);
1773 }
1774#else
1775 av_log(NULL, AV_LOG_STDERR, "No filters available: libavfilter disabled\n");
1776#endif
1777 return 0;
1778}
1779
1780int show_colors(void *optctx, const char *opt, const char *arg)
1781{
1782 const char *name;
1783 const uint8_t *rgb;
1784 int i;
1785
1786 av_log(NULL, AV_LOG_STDERR, "%-32s #RRGGBB\n", "name");
1787
1788 for (i = 0; (name = av_get_known_color_name(i, &rgb)); i++)
1789 av_log(NULL, AV_LOG_STDERR, "%-32s #%02x%02x%02x\n", name, rgb[0], rgb[1], rgb[2]);
1790
1791 return 0;
1792}
1793
1794int show_pix_fmts(void *optctx, const char *opt, const char *arg)
1795{
1796 const AVPixFmtDescriptor *pix_desc = NULL;
1797
1798 av_log(NULL, AV_LOG_STDERR, "Pixel formats:\n"
1799 "I.... = Supported Input format for conversion\n"
1800 ".O... = Supported Output format for conversion\n"
1801 "..H.. = Hardware accelerated format\n"
1802 "...P. = Paletted format\n"
1803 "....B = Bitstream format\n"
1804 "FLAGS NAME NB_COMPONENTS BITS_PER_PIXEL\n"
1805 "-----\n");
1806
1807#if !CONFIG_SWSCALE
1808# define sws_isSupportedInput(x) 0
1809# define sws_isSupportedOutput(x) 0
1810#endif
1811
1812 while ((pix_desc = av_pix_fmt_desc_next(pix_desc))) {
1813 enum AVPixelFormat av_unused pix_fmt = av_pix_fmt_desc_get_id(pix_desc);
1814 av_log(NULL, AV_LOG_STDERR, "%c%c%c%c%c %-16s %d %2d\n",
1815 sws_isSupportedInput (pix_fmt) ? 'I' : '.',
1816 sws_isSupportedOutput(pix_fmt) ? 'O' : '.',
1817 pix_desc->flags & AV_PIX_FMT_FLAG_HWACCEL ? 'H' : '.',
1818 pix_desc->flags & AV_PIX_FMT_FLAG_PAL ? 'P' : '.',
1819 pix_desc->flags & AV_PIX_FMT_FLAG_BITSTREAM ? 'B' : '.',
1820 pix_desc->name,
1821 pix_desc->nb_components,
1822 av_get_bits_per_pixel(pix_desc));
1823 }
1824 return 0;
1825}
1826
1827int show_layouts(void *optctx, const char *opt, const char *arg)
1828{
1829 int i = 0;
1830 uint64_t layout, j;
1831 const char *name, *descr;
1832
1833 av_log(NULL, AV_LOG_STDERR, "Individual channels:\n"
1834 "NAME DESCRIPTION\n");
1835 for (i = 0; i < 63; i++) {
1836 name = av_get_channel_name((uint64_t)1 << i);
1837 if (!name)
1838 continue;
1839 descr = av_get_channel_description((uint64_t)1 << i);
1840 av_log(NULL, AV_LOG_STDERR, "%-14s %s\n", name, descr);
1841 }
1842 av_log(NULL, AV_LOG_STDERR, "\nStandard channel layouts:\n"
1843 "NAME DECOMPOSITION\n");
1844 for (i = 0; !av_get_standard_channel_layout(i, &layout, &name); i++) {
1845 if (name) {
1846 av_log(NULL, AV_LOG_STDERR, "%-14s ", name);
1847 for (j = 1; j; j <<= 1)
1848 if ((layout & j))
1849 av_log(NULL, AV_LOG_STDERR, "%s%s", (layout & (j - 1)) ? "+" : "", av_get_channel_name(j));
1850 av_log(NULL, AV_LOG_STDERR, "\n");
1851 }
1852 }
1853 return 0;
1854}
1855
1856int show_sample_fmts(void *optctx, const char *opt, const char *arg)
1857{
1858 int i;
1859 char fmt_str[128];
1860 for (i = -1; i < AV_SAMPLE_FMT_NB; i++)
1861 av_log(NULL, AV_LOG_STDERR, "%s\n", av_get_sample_fmt_string(fmt_str, sizeof(fmt_str), i));
1862 return 0;
1863}
1864
1865static void show_help_codec(const char *name, int encoder)
1866{
1867 const AVCodecDescriptor *desc;
1868 const AVCodec *codec;
1869
1870 if (!name) {
1871 av_log(NULL, AV_LOG_ERROR, "No codec name specified.\n");
1872 return;
1873 }
1874
1875 codec = encoder ? avcodec_find_encoder_by_name(name) :
1876 avcodec_find_decoder_by_name(name);
1877
1878 if (codec)
1879 print_codec(codec);
1880 else if ((desc = avcodec_descriptor_get_by_name(name))) {
1881 void *iter = NULL;
1882 int printed = 0;
1883
1884 while ((codec = next_codec_for_id(desc->id, &iter, encoder))) {
1885 printed = 1;
1886 print_codec(codec);
1887 }
1888
1889 if (!printed) {
1890 av_log(NULL, AV_LOG_ERROR, "Codec '%s' is known to FFmpeg, "
1891 "but no %s for it are available. FFmpeg might need to be "
1892 "recompiled with additional external libraries.\n",
1893 name, encoder ? "encoders" : "decoders");
1894 }
1895 } else {
1896 av_log(NULL, AV_LOG_ERROR, "Codec '%s' is not recognized by FFmpeg.\n",
1897 name);
1898 }
1899}
1900
1901static void show_help_demuxer(const char *name)
1902{
1903 const AVInputFormat *fmt = av_find_input_format(name);
1904
1905 if (!fmt) {
1906 av_log(NULL, AV_LOG_ERROR, "Unknown format '%s'.\n", name);
1907 return;
1908 }
1909
1910 av_log(NULL, AV_LOG_STDERR, "Demuxer %s [%s]:\n", fmt->name, fmt->long_name);
1911
1912 if (fmt->extensions)
1913 av_log(NULL, AV_LOG_STDERR, " Common extensions: %s.\n", fmt->extensions);
1914
1915 if (fmt->priv_class)
1916 show_help_children(fmt->priv_class, AV_OPT_FLAG_DECODING_PARAM);
1917}
1918
1919static void show_help_protocol(const char *name)
1920{
1921 const AVClass *proto_class;
1922
1923 if (!name) {
1924 av_log(NULL, AV_LOG_ERROR, "No protocol name specified.\n");
1925 return;
1926 }
1927
1928 proto_class = avio_protocol_get_class(name);
1929 if (!proto_class) {
1930 av_log(NULL, AV_LOG_ERROR, "Unknown protocol '%s'.\n", name);
1931 return;
1932 }
1933
1934 show_help_children(proto_class, AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_ENCODING_PARAM);
1935}
1936
1937static void show_help_muxer(const char *name)
1938{
1939 const AVCodecDescriptor *desc;
1940 const AVOutputFormat *fmt = av_guess_format(name, NULL, NULL);
1941
1942 if (!fmt) {
1943 av_log(NULL, AV_LOG_ERROR, "Unknown format '%s'.\n", name);
1944 return;
1945 }
1946
1947 av_log(NULL, AV_LOG_STDERR, "Muxer %s [%s]:\n", fmt->name, fmt->long_name);
1948
1949 if (fmt->extensions)
1950 av_log(NULL, AV_LOG_STDERR, " Common extensions: %s.\n", fmt->extensions);
1951 if (fmt->mime_type)
1952 av_log(NULL, AV_LOG_STDERR, " Mime type: %s.\n", fmt->mime_type);
1953 if (fmt->video_codec != AV_CODEC_ID_NONE &&
1954 (desc = avcodec_descriptor_get(fmt->video_codec))) {
1955 av_log(NULL, AV_LOG_STDERR, " Default video codec: %s.\n", desc->name);
1956 }
1957 if (fmt->audio_codec != AV_CODEC_ID_NONE &&
1958 (desc = avcodec_descriptor_get(fmt->audio_codec))) {
1959 av_log(NULL, AV_LOG_STDERR, " Default audio codec: %s.\n", desc->name);
1960 }
1961 if (fmt->subtitle_codec != AV_CODEC_ID_NONE &&
1962 (desc = avcodec_descriptor_get(fmt->subtitle_codec))) {
1963 av_log(NULL, AV_LOG_STDERR, " Default subtitle codec: %s.\n", desc->name);
1964 }
1965
1966 if (fmt->priv_class)
1967 show_help_children(fmt->priv_class, AV_OPT_FLAG_ENCODING_PARAM);
1968}
1969
1970#if CONFIG_AVFILTER
1971static void show_help_filter(const char *name)
1972{
1973#if CONFIG_AVFILTER
1974 const AVFilter *f = avfilter_get_by_name(name);
1975 int i, count;
1976
1977 if (!name) {
1978 av_log(NULL, AV_LOG_ERROR, "No filter name specified.\n");
1979 return;
1980 } else if (!f) {
1981 av_log(NULL, AV_LOG_ERROR, "Unknown filter '%s'.\n", name);
1982 return;
1983 }
1984
1985 av_log(NULL, AV_LOG_STDERR, "Filter %s\n", f->name);
1986 if (f->description)
1987 av_log(NULL, AV_LOG_STDERR, " %s\n", f->description);
1988
1989 if (f->flags & AVFILTER_FLAG_SLICE_THREADS)
1990 av_log(NULL, AV_LOG_STDERR, " slice threading supported\n");
1991
1992 av_log(NULL, AV_LOG_STDERR, " Inputs:\n");
1993 count = avfilter_pad_count(f->inputs);
1994 for (i = 0; i < count; i++) {
1995 av_log(NULL, AV_LOG_STDERR, " #%d: %s (%s)\n", i, avfilter_pad_get_name(f->inputs, i),
1996 media_type_string(avfilter_pad_get_type(f->inputs, i)));
1997 }
1998 if (f->flags & AVFILTER_FLAG_DYNAMIC_INPUTS)
1999 av_log(NULL, AV_LOG_STDERR, " dynamic (depending on the options)\n");
2000 else if (!count)
2001 av_log(NULL, AV_LOG_STDERR, " none (source filter)\n");
2002
2003 av_log(NULL, AV_LOG_STDERR, " Outputs:\n");
2004 count = avfilter_pad_count(f->outputs);
2005 for (i = 0; i < count; i++) {
2006 av_log(NULL, AV_LOG_STDERR, " #%d: %s (%s)\n", i, avfilter_pad_get_name(f->outputs, i),
2007 media_type_string(avfilter_pad_get_type(f->outputs, i)));
2008 }
2009 if (f->flags & AVFILTER_FLAG_DYNAMIC_OUTPUTS)
2010 av_log(NULL, AV_LOG_STDERR, " dynamic (depending on the options)\n");
2011 else if (!count)
2012 av_log(NULL, AV_LOG_STDERR, " none (sink filter)\n");
2013
2014 if (f->priv_class)
2015 show_help_children(f->priv_class, AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_FILTERING_PARAM |
2016 AV_OPT_FLAG_AUDIO_PARAM);
2017 if (f->flags & AVFILTER_FLAG_SUPPORT_TIMELINE)
2018 av_log(NULL, AV_LOG_STDERR, "This filter has support for timeline through the 'enable' option.\n");
2019#else
2020 av_log(NULL, AV_LOG_ERROR, "Build without libavfilter; "
2021 "can not to satisfy request\n");
2022#endif
2023}
2024#endif
2025
2026static void show_help_bsf(const char *name)
2027{
2028 const AVBitStreamFilter *bsf = av_bsf_get_by_name(name);
2029
2030 if (!name) {
2031 av_log(NULL, AV_LOG_ERROR, "No bitstream filter name specified.\n");
2032 return;
2033 } else if (!bsf) {
2034 av_log(NULL, AV_LOG_ERROR, "Unknown bit stream filter '%s'.\n", name);
2035 return;
2036 }
2037
2038 av_log(NULL, AV_LOG_STDERR, "Bit stream filter %s\n", bsf->name);
2039 PRINT_CODEC_SUPPORTED(bsf, codec_ids, enum AVCodecID, "codecs",
2040 AV_CODEC_ID_NONE, GET_CODEC_NAME);
2041 if (bsf->priv_class)
2042 show_help_children(bsf->priv_class, AV_OPT_FLAG_BSF_PARAM);
2043}
2044
2045int show_help(void *optctx, const char *opt, const char *arg)
2046{
2047 char *topic, *par;
2048
2049 topic = av_strdup(arg ? arg : "");
2050 if (!topic)
2051 return AVERROR(ENOMEM);
2052 par = strchr(topic, '=');
2053 if (par)
2054 *par++ = 0;
2055
2056 if (!*topic) {
2057 if (program_name && !strcmp(program_name, "ffmpeg")) {
2058 show_help_default_ffmpeg(topic, par);
2059 } else {
2060 show_help_default_ffprobe(topic, par);
2061 }
2062 } else if (!strcmp(topic, "decoder")) {
2063 show_help_codec(par, 0);
2064 } else if (!strcmp(topic, "encoder")) {
2065 show_help_codec(par, 1);
2066 } else if (!strcmp(topic, "demuxer")) {
2067 show_help_demuxer(par);
2068 } else if (!strcmp(topic, "muxer")) {
2069 show_help_muxer(par);
2070 } else if (!strcmp(topic, "protocol")) {
2071 show_help_protocol(par);
2072#if CONFIG_AVFILTER
2073 } else if (!strcmp(topic, "filter")) {
2074 show_help_filter(par);
2075#endif
2076 } else if (!strcmp(topic, "bsf")) {
2077 show_help_bsf(par);
2078 } else {
2079 if (program_name && !strcmp(program_name, "ffmpeg")) {
2080 show_help_default_ffmpeg(topic, par);
2081 } else {
2082 show_help_default_ffprobe(topic, par);
2083 }
2084 }
2085
2086 av_freep(&topic);
2087 return 0;
2088}
2089
2090int read_yesno(void)
2091{
2092 int c = getchar();
2093 int yesno = (av_toupper(c) == 'Y');
2094
2095 while (c != '\n' && c != EOF)
2096 c = getchar();
2097
2098 return yesno;
2099}
2100
2101FILE *get_preset_file(char *filename, size_t filename_size,
2102 const char *preset_name, int is_path,
2103 const char *codec_name)
2104{
2105 FILE *f = NULL;
2106 int i;
2107 const char *base[3] = { getenv("FFMPEG_DATADIR"),
2108 getenv("HOME"),
2109 FFMPEG_DATADIR, };
2110
2111 if (is_path) {
2112 av_strlcpy(filename, preset_name, filename_size);
2113 f = fopen(filename, "r");
2114 } else {
2115#if HAVE_GETMODULEHANDLE && defined(_WIN32)
2116 char datadir[MAX_PATH], *ls;
2117 base[2] = NULL;
2118
2119 if (GetModuleFileNameA(GetModuleHandleA(NULL), datadir, sizeof(datadir) - 1))
2120 {
2121 for (ls = datadir; ls < datadir + strlen(datadir); ls++)
2122 if (*ls == '\\') *ls = '/';
2123
2124 if (ls = strrchr(datadir, '/'))
2125 {
2126 *ls = 0;
2127 strncat(datadir, "/ffpresets", sizeof(datadir) - 1 - strlen(datadir));
2128 base[2] = datadir;
2129 }
2130 }
2131#endif
2132 for (i = 0; i < 3 && !f; i++) {
2133 if (!base[i])
2134 continue;
2135 snprintf(filename, filename_size, "%s%s/%s.ffpreset", base[i],
2136 i != 1 ? "" : "/.ffmpeg", preset_name);
2137 f = fopen(filename, "r");
2138 if (!f && codec_name) {
2139 snprintf(filename, filename_size,
2140 "%s%s/%s-%s.ffpreset",
2141 base[i], i != 1 ? "" : "/.ffmpeg", codec_name,
2142 preset_name);
2143 f = fopen(filename, "r");
2144 }
2145 }
2146 }
2147
2148 return f;
2149}
2150
2151int check_stream_specifier(AVFormatContext *s, AVStream *st, const char *spec)
2152{
2153 int ret = avformat_match_stream_specifier(s, st, spec);
2154 if (ret < 0)
2155 av_log(s, AV_LOG_ERROR, "Invalid stream specifier: %s.\n", spec);
2156 return ret;
2157}
2158
2159AVDictionary *filter_codec_opts(AVDictionary *opts, enum AVCodecID codec_id,
2160 AVFormatContext *s, AVStream *st, const AVCodec *codec)
2161{
2162 AVDictionary *ret = NULL;
2163 AVDictionaryEntry *t = NULL;
2164 int flags = s->oformat ? AV_OPT_FLAG_ENCODING_PARAM
2165 : AV_OPT_FLAG_DECODING_PARAM;
2166 char prefix = 0;
2167 const AVClass *cc = avcodec_get_class();
2168
2169 if (!codec)
2170 codec = s->oformat ? avcodec_find_encoder(codec_id)
2171 : avcodec_find_decoder(codec_id);
2172
2173 switch (st->codecpar->codec_type) {
2174 case AVMEDIA_TYPE_VIDEO:
2175 prefix = 'v';
2176 flags |= AV_OPT_FLAG_VIDEO_PARAM;
2177 break;
2178 case AVMEDIA_TYPE_AUDIO:
2179 prefix = 'a';
2180 flags |= AV_OPT_FLAG_AUDIO_PARAM;
2181 break;
2182 case AVMEDIA_TYPE_SUBTITLE:
2183 prefix = 's';
2184 flags |= AV_OPT_FLAG_SUBTITLE_PARAM;
2185 break;
2186 }
2187
2188 while ((t = av_dict_get(opts, "", t, AV_DICT_IGNORE_SUFFIX))) {
2189 const AVClass *priv_class;
2190 char *p = strchr(t->key, ':');
2191
2192 /* check stream specification in opt name */
2193 if (p)
2194 switch (check_stream_specifier(s, st, p + 1)) {
2195 case 1: *p = 0; break;
2196 case 0: continue;
2197 default: exit_program(1);
2198 }
2199
2200 if (av_opt_find(&cc, t->key, NULL, flags, AV_OPT_SEARCH_FAKE_OBJ) ||
2201 !codec ||
2202 ((priv_class = codec->priv_class) &&
2203 av_opt_find(&priv_class, t->key, NULL, flags,
2204 AV_OPT_SEARCH_FAKE_OBJ)))
2205 av_dict_set(&ret, t->key, t->value, 0);
2206 else if (t->key[0] == prefix &&
2207 av_opt_find(&cc, t->key + 1, NULL, flags,
2208 AV_OPT_SEARCH_FAKE_OBJ))
2209 av_dict_set(&ret, t->key + 1, t->value, 0);
2210
2211 if (p)
2212 *p = ':';
2213 }
2214 return ret;
2215}
2216
2217AVDictionary **setup_find_stream_info_opts(AVFormatContext *s,
2218 AVDictionary *codec_opts)
2219{
2220 int i;
2221 AVDictionary **opts;
2222
2223 if (!s->nb_streams)
2224 return NULL;
2225 opts = av_mallocz_array(s->nb_streams, sizeof(*opts));
2226 if (!opts) {
2227 av_log(NULL, AV_LOG_ERROR,
2228 "Could not alloc memory for stream options.\n");
2229 return NULL;
2230 }
2231 for (i = 0; i < s->nb_streams; i++)
2232 opts[i] = filter_codec_opts(codec_opts, s->streams[i]->codecpar->codec_id,
2233 s, s->streams[i], NULL);
2234 return opts;
2235}
2236
2237void *grow_array(void *array, int elem_size, int *size, int new_size)
2238{
2239 if (new_size >= INT_MAX / elem_size) {
2240 av_log(NULL, AV_LOG_ERROR, "Array too big.\n");
2241 exit_program(1);
2242 }
2243 if (*size < new_size) {
2244 uint8_t *tmp = av_realloc_array(array, new_size, elem_size);
2245 if (!tmp) {
2246 av_log(NULL, AV_LOG_ERROR, "Could not alloc buffer.\n");
2247 exit_program(1);
2248 }
2249 memset(tmp + *size*elem_size, 0, (new_size-*size) * elem_size);
2250 *size = new_size;
2251 return tmp;
2252 }
2253 return array;
2254}
2255
2256double get_rotation(AVStream *st)
2257{
2258 uint8_t* displaymatrix = av_stream_get_side_data(st,
2259 AV_PKT_DATA_DISPLAYMATRIX, NULL);
2260 double theta = 0;
2261 if (displaymatrix)
2262 theta = -av_display_rotation_get((int32_t*) displaymatrix);
2263
2264 theta -= 360*floor(theta/360 + 0.9/360);
2265
2266 if (fabs(theta - 90*round(theta/90)) > 2)
2267 av_log(NULL, AV_LOG_WARNING, "Odd rotation angle.\n"
2268 "If you want to help, upload a sample "
2269 "of this file to https://streams.videolan.org/upload/ "
2270 "and contact the ffmpeg-devel mailing list. (ffmpeg-devel@ffmpeg.org)");
2271
2272 return theta;
2273}
2274
2275#if CONFIG_AVDEVICE
2276static int print_device_sources(const AVInputFormat *fmt, AVDictionary *opts)
2277{
2278 int ret, i;
2279 AVDeviceInfoList *device_list = NULL;
2280
2281 if (!fmt || !fmt->priv_class || !AV_IS_INPUT_DEVICE(fmt->priv_class->category))
2282 return AVERROR(EINVAL);
2283
2284 av_log(NULL, AV_LOG_STDERR, "Auto-detected sources for %s:\n", fmt->name);
2285 if (!fmt->get_device_list) {
2286 ret = AVERROR(ENOSYS);
2287 av_log(NULL, AV_LOG_STDERR, "Cannot list sources. Not implemented.\n");
2288 goto fail;
2289 }
2290
2291 if ((ret = avdevice_list_input_sources(fmt, NULL, opts, &device_list)) < 0) {
2292 av_log(NULL, AV_LOG_STDERR, "Cannot list sources.\n");
2293 goto fail;
2294 }
2295
2296 for (i = 0; i < device_list->nb_devices; i++) {
2297 av_log(NULL, AV_LOG_STDERR, "%s %s [%s]\n", device_list->default_device == i ? "*" : " ",
2298 device_list->devices[i]->device_name, device_list->devices[i]->device_description);
2299 }
2300
2301 fail:
2302 avdevice_free_list_devices(&device_list);
2303 return ret;
2304}
2305
2306static int print_device_sinks(const AVOutputFormat *fmt, AVDictionary *opts)
2307{
2308 int ret, i;
2309 AVDeviceInfoList *device_list = NULL;
2310
2311 if (!fmt || !fmt->priv_class || !AV_IS_OUTPUT_DEVICE(fmt->priv_class->category))
2312 return AVERROR(EINVAL);
2313
2314 av_log(NULL, AV_LOG_STDERR, "Auto-detected sinks for %s:\n", fmt->name);
2315 if (!fmt->get_device_list) {
2316 ret = AVERROR(ENOSYS);
2317 av_log(NULL, AV_LOG_STDERR, "Cannot list sinks. Not implemented.\n");
2318 goto fail;
2319 }
2320
2321 if ((ret = avdevice_list_output_sinks(fmt, NULL, opts, &device_list)) < 0) {
2322 av_log(NULL, AV_LOG_STDERR, "Cannot list sinks.\n");
2323 goto fail;
2324 }
2325
2326 for (i = 0; i < device_list->nb_devices; i++) {
2327 av_log(NULL, AV_LOG_STDERR, "%s %s [%s]\n", device_list->default_device == i ? "*" : " ",
2328 device_list->devices[i]->device_name, device_list->devices[i]->device_description);
2329 }
2330
2331 fail:
2332 avdevice_free_list_devices(&device_list);
2333 return ret;
2334}
2335
2336static int show_sinks_sources_parse_arg(const char *arg, char **dev, AVDictionary **opts)
2337{
2338 int ret;
2339 if (arg) {
2340 char *opts_str = NULL;
2341 av_assert0(dev && opts);
2342 *dev = av_strdup(arg);
2343 if (!*dev)
2344 return AVERROR(ENOMEM);
2345 if ((opts_str = strchr(*dev, ','))) {
2346 *(opts_str++) = '\0';
2347 if (opts_str[0] && ((ret = av_dict_parse_string(opts, opts_str, "=", ":", 0)) < 0)) {
2348 av_freep(dev);
2349 return ret;
2350 }
2351 }
2352 } else
2353 av_log(NULL, AV_LOG_STDERR, "\nDevice name is not provided.\n"
2354 "You can pass devicename[,opt1=val1[,opt2=val2...]] as an argument.\n\n");
2355 return 0;
2356}
2357
2358int show_sources(void *optctx, const char *opt, const char *arg)
2359{
2360 const AVInputFormat *fmt = NULL;
2361 char *dev = NULL;
2362 AVDictionary *opts = NULL;
2363 int ret = 0;
2364 int error_level = av_log_get_level();
2365
2366 av_log_set_level(AV_LOG_WARNING);
2367
2368 if ((ret = show_sinks_sources_parse_arg(arg, &dev, &opts)) < 0)
2369 goto fail;
2370
2371 do {
2372 fmt = av_input_audio_device_next(fmt);
2373 if (fmt) {
2374 if (!strcmp(fmt->name, "lavfi"))
2375 continue; //it's pointless to probe lavfi
2376 if (dev && !av_match_name(dev, fmt->name))
2377 continue;
2378 print_device_sources(fmt, opts);
2379 }
2380 } while (fmt);
2381 do {
2382 fmt = av_input_video_device_next(fmt);
2383 if (fmt) {
2384 if (dev && !av_match_name(dev, fmt->name))
2385 continue;
2386 print_device_sources(fmt, opts);
2387 }
2388 } while (fmt);
2389 fail:
2390 av_dict_free(&opts);
2391 av_free(dev);
2392 av_log_set_level(error_level);
2393 return ret;
2394}
2395
2396int show_sinks(void *optctx, const char *opt, const char *arg)
2397{
2398 const AVOutputFormat *fmt = NULL;
2399 char *dev = NULL;
2400 AVDictionary *opts = NULL;
2401 int ret = 0;
2402 int error_level = av_log_get_level();
2403
2404 av_log_set_level(AV_LOG_WARNING);
2405
2406 if ((ret = show_sinks_sources_parse_arg(arg, &dev, &opts)) < 0)
2407 goto fail;
2408
2409 do {
2410 fmt = av_output_audio_device_next(fmt);
2411 if (fmt) {
2412 if (dev && !av_match_name(dev, fmt->name))
2413 continue;
2414 print_device_sinks(fmt, opts);
2415 }
2416 } while (fmt);
2417 do {
2418 fmt = av_output_video_device_next(fmt);
2419 if (fmt) {
2420 if (dev && !av_match_name(dev, fmt->name))
2421 continue;
2422 print_device_sinks(fmt, opts);
2423 }
2424 } while (fmt);
2425 fail:
2426 av_dict_free(&opts);
2427 av_free(dev);
2428 av_log_set_level(error_level);
2429 return ret;
2430}
2431
2432#endif
__thread jmp_buf ex_buf__
void exit_program(int ret)
__thread AVDictionary * swr_opts
static int match_group_separator(const OptionGroupDef *groups, int nb_groups, const char *opt)
int show_decoders(void *optctx, const char *opt, const char *arg)
int opt_loglevel(void *optctx, const char *opt, const char *arg)
void show_help_children(const AVClass *class, int flags)
__thread AVDictionary * codec_opts
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)
Definition: ffmpegkit.c:443
static void prepare_app_arguments(int *argc_ptr, char ***argv_ptr)
void init_dynload(void)
int parse_option(void *optctx, const char *opt, const char *arg, const OptionDef *options)
int show_help(void *optctx, const char *opt, const char *arg)
void show_help_options(const OptionDef *options, const char *msg, int req_flags, int rej_flags, int alt_flags)
__thread AVDictionary * format_opts
static void show_help_bsf(const char *name)
int opt_default(void *optctx, const char *opt, const char *arg)
void print_error(const char *filename, int err)
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)
__thread volatile int longjmp_value
int show_sample_fmts(void *optctx, const char *opt, const char *arg)
#define SHOW_CONFIG
int read_yesno(void)
int report_file_level
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)
int locate_option(int argc, char **argv, const OptionDef *options, const char *optname)
static const AVOption * opt_find(void *obj, const char *name, const char *unit, int opt_flags, int search_flags)
#define INDENT
static int compare_codec_desc(const void *a, const void *b)
int show_bsfs(void *optctx, const char *opt, const char *arg)
FILE * report_file
static int write_option(void *optctx, const OptionDef *po, const char *opt, const char *arg)
static void print_all_libs_info(int flags, int level)
int check_stream_specifier(AVFormatContext *s, AVStream *st, const char *spec)
__thread AVDictionary * resample_opts
static void init_parse_context(OptionParseContext *octx, const OptionGroupDef *groups, int nb_groups)
static void add_opt(OptionParseContext *octx, const OptionDef *opt, const char *key, const char *val)
__thread char * program_name
#define FLAGS
static void print_buildconf(int flags, int level)
#define PRINT_LIB_INFO(libname, LIBNAME, flags, level)
int show_layouts(void *optctx, const char *opt, const char *arg)
static __thread void(* program_exit)(int ret)
static void dump_argument(const char *a)
int show_encoders(void *optctx, const char *opt, const char *arg)
#define GET_ARG(arg)
static void finish_group(OptionParseContext *octx, int group_idx, 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)
void parse_loglevel(int argc, char **argv, const OptionDef *options)
static void show_help_protocol(const char *name)
__thread int program_birth_year
__thread int warned_cfg
void parse_options(void *optctx, int argc, char **argv, const OptionDef *options, void(*parse_arg_function)(void *, const char *))
static char get_media_type_char(enum AVMediaType type)
int opt_cpucount(void *optctx, const char *opt, const char *arg)
void uninit_parse_context(OptionParseContext *octx)
__thread AVDictionary * sws_dict
int split_commandline(OptionParseContext *octx, int argc, char *argv[], const OptionDef *options, const OptionGroupDef *groups, int nb_groups)
double get_rotation(AVStream *st)
void show_banner(int argc, char **argv, const OptionDef *options)
static void show_help_muxer(const char *name)
int opt_timelimit(void *optctx, const char *opt, const char *arg)
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)
int64_t parse_time_or_die(const char *context, const char *timestr, int is_duration)
void register_exit(void(*cb)(int ret))
static int show_formats_devices(void *optctx, const char *opt, const char *arg, int device_only, int muxdemuxers)
FILE * get_preset_file(char *filename, size_t filename_size, const char *preset_name, int is_path, const char *codec_name)
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
void log_callback_report(void *ptr, int level, const char *fmt, va_list vl)
void uninit_opts(void)
static void print_codec(const AVCodec *c)
int show_formats(void *optctx, const char *opt, const char *arg)
void * grow_array(void *array, int elem_size, int *size, int new_size)
AVDictionary * filter_codec_opts(AVDictionary *opts, enum AVCodecID codec_id, AVFormatContext *s, AVStream *st, const AVCodec *codec)
static const OptionDef * find_option(const OptionDef *po, const char *name)
__thread int hide_banner
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 parse_optgroup(void *optctx, OptionGroup *g)
int opt_max_alloc(void *optctx, const char *opt, const char *arg)
static void check_options(const OptionDef *po)
int opt_report(void *optctx, const char *opt, const char *arg)
int show_colors(void *optctx, const char *opt, const char *arg)
double parse_number_or_die(const char *context, const char *numstr, int type, double min, double max)
static int init_report(const char *env)
#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)
AVDictionary ** setup_find_stream_info_opts(AVFormatContext *s, AVDictionary *codec_opts)
#define GET_SAMPLE_RATE_NAME(rate)
#define OPT_SPEC
#define OPT_BOOL
#define media_type_string
#define OPT_INT64
#define OPT_PERFILE
#define GET_CODEC_NAME(id)
#define OPT_INT
#define OPT_FLOAT
#define AV_LOG_STDERR
#define OPT_INPUT
#define GET_PIX_FMT_NAME(pix_fmt)
#define OPT_DOUBLE
#define OPT_STRING
#define GET_CH_LAYOUT_DESC(ch_layout)
#define GROW_ARRAY(array, nb_elems)
#define GET_SAMPLE_FMT_NAME(sample_fmt)
#define OPT_EXIT
#define OPT_OUTPUT
#define OPT_TIME
void show_help_default_ffprobe(const char *opt, const char *arg)
void show_help_default_ffmpeg(const char *opt, const char *arg)
#define OPT_OFFSET
#define HAS_ARG
static int decode(AVCodecContext *avctx, AVFrame *frame, int *got_frame, AVPacket *pkt)
ost filter
fg outputs[0] format
union OptionDef::@1 u
const char * name
const char * argname
const char * help
int(* func_arg)(void *, const char *, const char *)
const char * name
const char * sep
const OptionGroupDef * group_def
AVDictionary * codec_opts
AVDictionary * swr_opts
AVDictionary * sws_dict
const char * arg
AVDictionary * format_opts
AVDictionary * resample_opts
OptionGroup * groups
const OptionGroupDef * group_def
const char * key
const OptionDef * opt
const char * val
OptionGroupList * groups