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