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