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