fftools: add -report option.
[ffmpeg.git] / cmdutils.c
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 <stdlib.h>
24 #include <errno.h>
25 #include <math.h>
26
27 /* Include only the enabled headers since some compilers (namely, Sun
28    Studio) will not omit unused inline functions and create undefined
29    references to libraries that are not being built. */
30
31 #include "config.h"
32 #include "libavformat/avformat.h"
33 #include "libavfilter/avfilter.h"
34 #include "libavdevice/avdevice.h"
35 #include "libswscale/swscale.h"
36 #include "libpostproc/postprocess.h"
37 #include "libavutil/avstring.h"
38 #include "libavutil/mathematics.h"
39 #include "libavutil/parseutils.h"
40 #include "libavutil/pixdesc.h"
41 #include "libavutil/eval.h"
42 #include "libavutil/dict.h"
43 #include "libavutil/opt.h"
44 #include "cmdutils.h"
45 #include "version.h"
46 #if CONFIG_NETWORK
47 #include "libavformat/network.h"
48 #endif
49 #if HAVE_SYS_RESOURCE_H
50 #include <sys/resource.h>
51 #endif
52
53 struct SwsContext *sws_opts;
54 AVDictionary *format_opts, *codec_opts;
55
56 static const int this_year = 2011;
57
58 static FILE *report_file;
59
60 void init_opts(void)
61 {
62 #if CONFIG_SWSCALE
63     sws_opts = sws_getContext(16, 16, 0, 16, 16, 0, SWS_BICUBIC, NULL, NULL, NULL);
64 #endif
65 }
66
67 void uninit_opts(void)
68 {
69 #if CONFIG_SWSCALE
70     sws_freeContext(sws_opts);
71     sws_opts = NULL;
72 #endif
73     av_dict_free(&format_opts);
74     av_dict_free(&codec_opts);
75 }
76
77 void log_callback_help(void* ptr, int level, const char* fmt, va_list vl)
78 {
79     vfprintf(stdout, fmt, vl);
80 }
81
82 static void log_callback_report(void *ptr, int level, const char *fmt, va_list vl)
83 {
84     va_list vl2;
85     char line[1024];
86     static int print_prefix = 1;
87
88     va_copy(vl2, vl);
89     av_log_default_callback(ptr, level, fmt, vl);
90     av_log_format_line(ptr, level, fmt, vl2, line, sizeof(line), &print_prefix);
91     va_end(vl2);
92     fputs(line, report_file);
93     fflush(report_file);
94 }
95
96 double parse_number_or_die(const char *context, const char *numstr, int type, double min, double max)
97 {
98     char *tail;
99     const char *error;
100     double d = av_strtod(numstr, &tail);
101     if (*tail)
102         error= "Expected number for %s but found: %s\n";
103     else if (d < min || d > max)
104         error= "The value for %s was %s which is not within %f - %f\n";
105     else if(type == OPT_INT64 && (int64_t)d != d)
106         error= "Expected int64 for %s but found %s\n";
107     else if (type == OPT_INT && (int)d != d)
108         error= "Expected int for %s but found %s\n";
109     else
110         return d;
111     av_log(NULL, AV_LOG_FATAL, error, context, numstr, min, max);
112     exit_program(1);
113     return 0;
114 }
115
116 int64_t parse_time_or_die(const char *context, const char *timestr, int is_duration)
117 {
118     int64_t us;
119     if (av_parse_time(&us, timestr, is_duration) < 0) {
120         av_log(NULL, AV_LOG_FATAL, "Invalid %s specification for %s: %s\n",
121                is_duration ? "duration" : "date", context, timestr);
122         exit_program(1);
123     }
124     return us;
125 }
126
127 void show_help_options(const OptionDef *options, const char *msg, int mask, int value)
128 {
129     const OptionDef *po;
130     int first;
131
132     first = 1;
133     for(po = options; po->name != NULL; po++) {
134         char buf[64];
135         if ((po->flags & mask) == value) {
136             if (first) {
137                 printf("%s", msg);
138                 first = 0;
139             }
140             av_strlcpy(buf, po->name, sizeof(buf));
141             if (po->flags & HAS_ARG) {
142                 av_strlcat(buf, " ", sizeof(buf));
143                 av_strlcat(buf, po->argname, sizeof(buf));
144             }
145             printf("-%-17s  %s\n", buf, po->help);
146         }
147     }
148 }
149
150 void show_help_children(const AVClass *class, int flags)
151 {
152     const AVClass *child = NULL;
153     av_opt_show2(&class, NULL, flags, 0);
154     printf("\n");
155
156     while (child = av_opt_child_class_next(class, child))
157         show_help_children(child, flags);
158 }
159
160 static const OptionDef* find_option(const OptionDef *po, const char *name){
161     const char *p = strchr(name, ':');
162     int len = p ? p - name : strlen(name);
163
164     while (po->name != NULL) {
165         if (!strncmp(name, po->name, len) && strlen(po->name) == len)
166             break;
167         po++;
168     }
169     return po;
170 }
171
172 #if defined(_WIN32) && !defined(__MINGW32CE__)
173 #include <windows.h>
174 /* Will be leaked on exit */
175 static char** win32_argv_utf8 = NULL;
176 static int win32_argc = 0;
177
178 /**
179  * Prepare command line arguments for executable.
180  * For Windows - perform wide-char to UTF-8 conversion.
181  * Input arguments should be main() function arguments.
182  * @param argc_ptr Arguments number (including executable)
183  * @param argv_ptr Arguments list.
184  */
185 static void prepare_app_arguments(int *argc_ptr, char ***argv_ptr)
186 {
187     char *argstr_flat;
188     wchar_t **argv_w;
189     int i, buffsize = 0, offset = 0;
190
191     if (win32_argv_utf8) {
192         *argc_ptr = win32_argc;
193         *argv_ptr = win32_argv_utf8;
194         return;
195     }
196
197     win32_argc = 0;
198     argv_w = CommandLineToArgvW(GetCommandLineW(), &win32_argc);
199     if (win32_argc <= 0 || !argv_w)
200         return;
201
202     /* determine the UTF-8 buffer size (including NULL-termination symbols) */
203     for (i = 0; i < win32_argc; i++)
204         buffsize += WideCharToMultiByte(CP_UTF8, 0, argv_w[i], -1,
205                                         NULL, 0, NULL, NULL);
206
207     win32_argv_utf8 = av_mallocz(sizeof(char*) * (win32_argc + 1) + buffsize);
208     argstr_flat     = (char*)win32_argv_utf8 + sizeof(char*) * (win32_argc + 1);
209     if (win32_argv_utf8 == NULL) {
210         LocalFree(argv_w);
211         return;
212     }
213
214     for (i = 0; i < win32_argc; i++) {
215         win32_argv_utf8[i] = &argstr_flat[offset];
216         offset += WideCharToMultiByte(CP_UTF8, 0, argv_w[i], -1,
217                                       &argstr_flat[offset],
218                                       buffsize - offset, NULL, NULL);
219     }
220     win32_argv_utf8[i] = NULL;
221     LocalFree(argv_w);
222
223     *argc_ptr = win32_argc;
224     *argv_ptr = win32_argv_utf8;
225 }
226 #else
227 static inline void prepare_app_arguments(int *argc_ptr, char ***argv_ptr)
228 {
229     /* nothing to do */
230 }
231 #endif /* WIN32 && !__MINGW32CE__ */
232
233
234 int parse_option(void *optctx, const char *opt, const char *arg, const OptionDef *options)
235 {
236     const OptionDef *po;
237     int bool_val = 1;
238     int *dstcount;
239     void *dst;
240
241     po = find_option(options, opt);
242     if (!po->name && opt[0] == 'n' && opt[1] == 'o') {
243         /* handle 'no' bool option */
244         po = find_option(options, opt + 2);
245         if (!(po->name && (po->flags & OPT_BOOL)))
246             goto unknown_opt;
247         bool_val = 0;
248     }
249     if (!po->name)
250         po = find_option(options, "default");
251     if (!po->name) {
252 unknown_opt:
253         av_log(NULL, AV_LOG_ERROR, "Unrecognized option '%s'\n", opt);
254         return AVERROR(EINVAL);
255     }
256     if (po->flags & HAS_ARG && !arg) {
257         av_log(NULL, AV_LOG_ERROR, "Missing argument for option '%s'\n", opt);
258         return AVERROR(EINVAL);
259     }
260
261     /* new-style options contain an offset into optctx, old-style address of
262      * a global var*/
263     dst = po->flags & (OPT_OFFSET|OPT_SPEC) ? (uint8_t*)optctx + po->u.off : po->u.dst_ptr;
264
265     if (po->flags & OPT_SPEC) {
266         SpecifierOpt **so = dst;
267         char *p = strchr(opt, ':');
268
269         dstcount = (int*)(so + 1);
270         *so = grow_array(*so, sizeof(**so), dstcount, *dstcount + 1);
271         (*so)[*dstcount - 1].specifier = av_strdup(p ? p + 1 : "");
272         dst = &(*so)[*dstcount - 1].u;
273     }
274
275     if (po->flags & OPT_STRING) {
276         char *str;
277         str = av_strdup(arg);
278         *(char**)dst = str;
279     } else if (po->flags & OPT_BOOL) {
280         *(int*)dst = bool_val;
281     } else if (po->flags & OPT_INT) {
282         *(int*)dst = parse_number_or_die(opt, arg, OPT_INT64, INT_MIN, INT_MAX);
283     } else if (po->flags & OPT_INT64) {
284         *(int64_t*)dst = parse_number_or_die(opt, arg, OPT_INT64, INT64_MIN, INT64_MAX);
285     } else if (po->flags & OPT_TIME) {
286         *(int64_t*)dst = parse_time_or_die(opt, arg, 1);
287     } else if (po->flags & OPT_FLOAT) {
288         *(float*)dst = parse_number_or_die(opt, arg, OPT_FLOAT, -INFINITY, INFINITY);
289     } else if (po->flags & OPT_DOUBLE) {
290         *(double*)dst = parse_number_or_die(opt, arg, OPT_DOUBLE, -INFINITY, INFINITY);
291     } else if (po->u.func_arg) {
292         int ret = po->flags & OPT_FUNC2 ? po->u.func2_arg(optctx, opt, arg) :
293                                           po->u.func_arg(opt, arg);
294         if (ret < 0) {
295             av_log(NULL, AV_LOG_ERROR, "Failed to set value '%s' for option '%s'\n", arg, opt);
296             return ret;
297         }
298     }
299     if (po->flags & OPT_EXIT)
300         exit_program(0);
301     return !!(po->flags & HAS_ARG);
302 }
303
304 void parse_options(void *optctx, int argc, char **argv, const OptionDef *options,
305                    void (* parse_arg_function)(void *, const char*))
306 {
307     const char *opt;
308     int optindex, handleoptions = 1, ret;
309
310     /* perform system-dependent conversions for arguments list */
311     prepare_app_arguments(&argc, &argv);
312
313     /* parse options */
314     optindex = 1;
315     while (optindex < argc) {
316         opt = argv[optindex++];
317
318         if (handleoptions && opt[0] == '-' && opt[1] != '\0') {
319             if (opt[1] == '-' && opt[2] == '\0') {
320                 handleoptions = 0;
321                 continue;
322             }
323             opt++;
324
325             if ((ret = parse_option(optctx, opt, argv[optindex], options)) < 0)
326                 exit_program(1);
327             optindex += ret;
328         } else {
329             if (parse_arg_function)
330                 parse_arg_function(optctx, opt);
331         }
332     }
333 }
334
335 /*
336  * Return index of option opt in argv or 0 if not found.
337  */
338 static int locate_option(int argc, char **argv, const OptionDef *options, const char *optname)
339 {
340     const OptionDef *po;
341     int i;
342
343     for (i = 1; i < argc; i++) {
344         const char *cur_opt = argv[i];
345
346         if (*cur_opt++ != '-')
347             continue;
348
349         po = find_option(options, cur_opt);
350         if (!po->name && cur_opt[0] == 'n' && cur_opt[1] == 'o')
351             po = find_option(options, cur_opt + 2);
352
353         if ((!po->name && !strcmp(cur_opt, optname)) ||
354              (po->name && !strcmp(optname, po->name)))
355             return i;
356
357         if (!po || po->flags & HAS_ARG)
358             i++;
359     }
360     return 0;
361 }
362
363 static void dump_argument(const char *a)
364 {
365     const unsigned char *p;
366
367     for (p = a; *p; p++)
368         if (!((*p >= '+' && *p <= ':') || (*p >= '@' && *p <= 'Z') ||
369               *p == '_' || (*p >= 'a' && *p <= 'z')))
370             break;
371     if (!*p) {
372         fputs(a, report_file);
373         return;
374     }
375     fputc('"', report_file);
376     for (p = a; *p; p++) {
377         if (*p == '\\' || *p == '"' || *p == '$' || *p == '`')
378             fprintf(report_file, "\\%c", *p);
379         else if (*p < ' ' || *p > '~')
380             fprintf(report_file, "\\x%02x", *p);
381         else
382             fputc(*p, report_file);
383     }
384     fputc('"', report_file);
385 }
386
387 void parse_loglevel(int argc, char **argv, const OptionDef *options)
388 {
389     int idx = locate_option(argc, argv, options, "loglevel");
390     if (!idx)
391         idx = locate_option(argc, argv, options, "v");
392     if (idx && argv[idx + 1])
393         opt_loglevel("loglevel", argv[idx + 1]);
394     idx = locate_option(argc, argv, options, "report");
395     if (idx || getenv("FFREPORT")) {
396         opt_report("report");
397         if (report_file) {
398             int i;
399             fprintf(report_file, "Command line:\n");
400             for (i = 0; i < argc; i++) {
401                 dump_argument(argv[i]);
402                 fputc(i < argc - 1 ? ' ' : '\n', report_file);
403             }
404             fflush(report_file);
405         }
406     }
407 }
408
409 #define FLAGS(o) ((o)->type == AV_OPT_TYPE_FLAGS) ? AV_DICT_APPEND : 0
410 int opt_default(const char *opt, const char *arg)
411 {
412     const AVOption *oc, *of, *os;
413     char opt_stripped[128];
414     const char *p;
415     const AVClass *cc = avcodec_get_class(), *fc = avformat_get_class(), *sc;
416
417     if (!(p = strchr(opt, ':')))
418         p = opt + strlen(opt);
419     av_strlcpy(opt_stripped, opt, FFMIN(sizeof(opt_stripped), p - opt + 1));
420
421     if ((oc = av_opt_find(&cc, opt_stripped, NULL, 0, AV_OPT_SEARCH_CHILDREN|AV_OPT_SEARCH_FAKE_OBJ)) ||
422          ((opt[0] == 'v' || opt[0] == 'a' || opt[0] == 's') &&
423           (oc = av_opt_find(&cc, opt+1, NULL, 0, AV_OPT_SEARCH_FAKE_OBJ))))
424         av_dict_set(&codec_opts, opt, arg, FLAGS(oc));
425     if ((of = av_opt_find(&fc, opt, NULL, 0, AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ)))
426         av_dict_set(&format_opts, opt, arg, FLAGS(of));
427 #if CONFIG_SWSCALE
428     sc = sws_get_class();
429     if ((os = av_opt_find(&sc, opt, NULL, 0, AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ))) {
430         // XXX we only support sws_flags, not arbitrary sws options
431         int ret = av_opt_set(sws_opts, opt, arg, 0);
432         if (ret < 0) {
433             av_log(NULL, AV_LOG_ERROR, "Error setting option %s.\n", opt);
434             return ret;
435         }
436     }
437 #endif
438
439     if (oc || of || os)
440         return 0;
441     av_log(NULL, AV_LOG_ERROR, "Unrecognized option '%s'\n", opt);
442     return AVERROR_OPTION_NOT_FOUND;
443 }
444
445 int opt_loglevel(const char *opt, const char *arg)
446 {
447     const struct { const char *name; int level; } log_levels[] = {
448         { "quiet"  , AV_LOG_QUIET   },
449         { "panic"  , AV_LOG_PANIC   },
450         { "fatal"  , AV_LOG_FATAL   },
451         { "error"  , AV_LOG_ERROR   },
452         { "warning", AV_LOG_WARNING },
453         { "info"   , AV_LOG_INFO    },
454         { "verbose", AV_LOG_VERBOSE },
455         { "debug"  , AV_LOG_DEBUG   },
456     };
457     char *tail;
458     int level;
459     int i;
460
461     for (i = 0; i < FF_ARRAY_ELEMS(log_levels); i++) {
462         if (!strcmp(log_levels[i].name, arg)) {
463             av_log_set_level(log_levels[i].level);
464             return 0;
465         }
466     }
467
468     level = strtol(arg, &tail, 10);
469     if (*tail) {
470         av_log(NULL, AV_LOG_FATAL, "Invalid loglevel \"%s\". "
471                "Possible levels are numbers or:\n", arg);
472         for (i = 0; i < FF_ARRAY_ELEMS(log_levels); i++)
473             av_log(NULL, AV_LOG_FATAL, "\"%s\"\n", log_levels[i].name);
474         exit_program(1);
475     }
476     av_log_set_level(level);
477     return 0;
478 }
479
480 int opt_report(const char *opt)
481 {
482     char filename[64];
483     time_t now;
484     struct tm *tm;
485
486     if (report_file) /* already opened */
487         return 0;
488     time(&now);
489     tm = localtime(&now);
490     snprintf(filename, sizeof(filename), "%s-%04d%02d%02d-%02d%02d%02d.log",
491              program_name,
492              tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
493              tm->tm_hour, tm->tm_min, tm->tm_sec);
494     report_file = fopen(filename, "w");
495     if (!report_file) {
496         av_log(NULL, AV_LOG_ERROR, "Failed to open report \"%s\": %s\n",
497                filename, strerror(errno));
498         return AVERROR(errno);
499     }
500     av_log_set_callback(log_callback_report);
501     av_log(NULL, AV_LOG_INFO,
502            "%s started on %04d-%02d-%02d at %02d:%02d:%02d\n"
503            "Report written to \"%s\"\n",
504            program_name,
505            tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
506            tm->tm_hour, tm->tm_min, tm->tm_sec,
507            filename);
508     av_log_set_level(FFMAX(av_log_get_level(), AV_LOG_VERBOSE));
509     return 0;
510 }
511
512 int opt_codec_debug(const char *opt, const char *arg)
513 {
514     av_log_set_level(AV_LOG_DEBUG);
515     return opt_default(opt, arg);
516 }
517
518 int opt_timelimit(const char *opt, const char *arg)
519 {
520 #if HAVE_SETRLIMIT
521     int lim = parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX);
522     struct rlimit rl = { lim, lim + 1 };
523     if (setrlimit(RLIMIT_CPU, &rl))
524         perror("setrlimit");
525 #else
526     av_log(NULL, AV_LOG_WARNING, "-%s not implemented on this OS\n", opt);
527 #endif
528     return 0;
529 }
530
531 void print_error(const char *filename, int err)
532 {
533     char errbuf[128];
534     const char *errbuf_ptr = errbuf;
535
536     if (av_strerror(err, errbuf, sizeof(errbuf)) < 0)
537         errbuf_ptr = strerror(AVUNERROR(err));
538     av_log(NULL, AV_LOG_ERROR, "%s: %s\n", filename, errbuf_ptr);
539 }
540
541 static int warned_cfg = 0;
542
543 #define INDENT        1
544 #define SHOW_VERSION  2
545 #define SHOW_CONFIG   4
546
547 #define PRINT_LIB_INFO(libname, LIBNAME, flags, level)                  \
548     if (CONFIG_##LIBNAME) {                                             \
549         const char *indent = flags & INDENT? "  " : "";                 \
550         if (flags & SHOW_VERSION) {                                     \
551             unsigned int version = libname##_version();                 \
552             av_log(NULL, level, "%slib%-9s %2d.%3d.%2d / %2d.%3d.%2d\n",\
553                    indent, #libname,                                    \
554                    LIB##LIBNAME##_VERSION_MAJOR,                        \
555                    LIB##LIBNAME##_VERSION_MINOR,                        \
556                    LIB##LIBNAME##_VERSION_MICRO,                        \
557                    version >> 16, version >> 8 & 0xff, version & 0xff); \
558         }                                                               \
559         if (flags & SHOW_CONFIG) {                                      \
560             const char *cfg = libname##_configuration();                \
561             if (strcmp(FFMPEG_CONFIGURATION, cfg)) {                    \
562                 if (!warned_cfg) {                                      \
563                     av_log(NULL, level,                                 \
564                             "%sWARNING: library configuration mismatch\n", \
565                             indent);                                    \
566                     warned_cfg = 1;                                     \
567                 }                                                       \
568                 av_log(NULL, level, "%s%-11s configuration: %s\n",      \
569                         indent, #libname, cfg);                         \
570             }                                                           \
571         }                                                               \
572     }                                                                   \
573
574 static void print_all_libs_info(int flags, int level)
575 {
576     PRINT_LIB_INFO(avutil,   AVUTIL,   flags, level);
577     PRINT_LIB_INFO(avcodec,  AVCODEC,  flags, level);
578     PRINT_LIB_INFO(avformat, AVFORMAT, flags, level);
579     PRINT_LIB_INFO(avdevice, AVDEVICE, flags, level);
580     PRINT_LIB_INFO(avfilter, AVFILTER, flags, level);
581     PRINT_LIB_INFO(swscale,  SWSCALE,  flags, level);
582     PRINT_LIB_INFO(postproc, POSTPROC, flags, level);
583 }
584
585 void show_banner(void)
586 {
587     av_log(NULL, AV_LOG_INFO, "%s version " FFMPEG_VERSION ", Copyright (c) %d-%d the FFmpeg developers\n",
588            program_name, program_birth_year, this_year);
589     av_log(NULL, AV_LOG_INFO, "  built on %s %s with %s %s\n",
590            __DATE__, __TIME__, CC_TYPE, CC_VERSION);
591     av_log(NULL, AV_LOG_INFO, "  configuration: " FFMPEG_CONFIGURATION "\n");
592     print_all_libs_info(INDENT|SHOW_CONFIG,  AV_LOG_INFO);
593     print_all_libs_info(INDENT|SHOW_VERSION, AV_LOG_INFO);
594 }
595
596 int opt_version(const char *opt, const char *arg) {
597     av_log_set_callback(log_callback_help);
598     printf("%s " FFMPEG_VERSION "\n", program_name);
599     print_all_libs_info(SHOW_VERSION, AV_LOG_INFO);
600     return 0;
601 }
602
603 int opt_license(const char *opt, const char *arg)
604 {
605     printf(
606 #if CONFIG_NONFREE
607     "This version of %s has nonfree parts compiled in.\n"
608     "Therefore it is not legally redistributable.\n",
609     program_name
610 #elif CONFIG_GPLV3
611     "%s is free software; you can redistribute it and/or modify\n"
612     "it under the terms of the GNU General Public License as published by\n"
613     "the Free Software Foundation; either version 3 of the License, or\n"
614     "(at your option) any later version.\n"
615     "\n"
616     "%s is distributed in the hope that it will be useful,\n"
617     "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
618     "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
619     "GNU General Public License for more details.\n"
620     "\n"
621     "You should have received a copy of the GNU General Public License\n"
622     "along with %s.  If not, see <http://www.gnu.org/licenses/>.\n",
623     program_name, program_name, program_name
624 #elif CONFIG_GPL
625     "%s is free software; you can redistribute it and/or modify\n"
626     "it under the terms of the GNU General Public License as published by\n"
627     "the Free Software Foundation; either version 2 of the License, or\n"
628     "(at your option) any later version.\n"
629     "\n"
630     "%s is distributed in the hope that it will be useful,\n"
631     "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
632     "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
633     "GNU General Public License for more details.\n"
634     "\n"
635     "You should have received a copy of the GNU General Public License\n"
636     "along with %s; if not, write to the Free Software\n"
637     "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n",
638     program_name, program_name, program_name
639 #elif CONFIG_LGPLV3
640     "%s is free software; you can redistribute it and/or modify\n"
641     "it under the terms of the GNU Lesser General Public License as published by\n"
642     "the Free Software Foundation; either version 3 of the License, or\n"
643     "(at your option) any later version.\n"
644     "\n"
645     "%s is distributed in the hope that it will be useful,\n"
646     "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
647     "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
648     "GNU Lesser General Public License for more details.\n"
649     "\n"
650     "You should have received a copy of the GNU Lesser General Public License\n"
651     "along with %s.  If not, see <http://www.gnu.org/licenses/>.\n",
652     program_name, program_name, program_name
653 #else
654     "%s is free software; you can redistribute it and/or\n"
655     "modify it under the terms of the GNU Lesser General Public\n"
656     "License as published by the Free Software Foundation; either\n"
657     "version 2.1 of the License, or (at your option) any later version.\n"
658     "\n"
659     "%s is distributed in the hope that it will be useful,\n"
660     "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
661     "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n"
662     "Lesser General Public License for more details.\n"
663     "\n"
664     "You should have received a copy of the GNU Lesser General Public\n"
665     "License along with %s; if not, write to the Free Software\n"
666     "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n",
667     program_name, program_name, program_name
668 #endif
669     );
670     return 0;
671 }
672
673 int opt_formats(const char *opt, const char *arg)
674 {
675     AVInputFormat *ifmt=NULL;
676     AVOutputFormat *ofmt=NULL;
677     const char *last_name;
678
679     printf(
680         "File formats:\n"
681         " D. = Demuxing supported\n"
682         " .E = Muxing supported\n"
683         " --\n");
684     last_name= "000";
685     for(;;){
686         int decode=0;
687         int encode=0;
688         const char *name=NULL;
689         const char *long_name=NULL;
690
691         while((ofmt= av_oformat_next(ofmt))) {
692             if((name == NULL || strcmp(ofmt->name, name)<0) &&
693                 strcmp(ofmt->name, last_name)>0){
694                 name= ofmt->name;
695                 long_name= ofmt->long_name;
696                 encode=1;
697             }
698         }
699         while((ifmt= av_iformat_next(ifmt))) {
700             if((name == NULL || strcmp(ifmt->name, name)<0) &&
701                 strcmp(ifmt->name, last_name)>0){
702                 name= ifmt->name;
703                 long_name= ifmt->long_name;
704                 encode=0;
705             }
706             if(name && strcmp(ifmt->name, name)==0)
707                 decode=1;
708         }
709         if(name==NULL)
710             break;
711         last_name= name;
712
713         printf(
714             " %s%s %-15s %s\n",
715             decode ? "D":" ",
716             encode ? "E":" ",
717             name,
718             long_name ? long_name:" ");
719     }
720     return 0;
721 }
722
723 int opt_codecs(const char *opt, const char *arg)
724 {
725     AVCodec *p=NULL, *p2;
726     const char *last_name;
727     printf(
728         "Codecs:\n"
729         " D..... = Decoding supported\n"
730         " .E.... = Encoding supported\n"
731         " ..V... = Video codec\n"
732         " ..A... = Audio codec\n"
733         " ..S... = Subtitle codec\n"
734         " ...S.. = Supports draw_horiz_band\n"
735         " ....D. = Supports direct rendering method 1\n"
736         " .....T = Supports weird frame truncation\n"
737         " ------\n");
738     last_name= "000";
739     for(;;){
740         int decode=0;
741         int encode=0;
742         int cap=0;
743         const char *type_str;
744
745         p2=NULL;
746         while((p= av_codec_next(p))) {
747             if((p2==NULL || strcmp(p->name, p2->name)<0) &&
748                 strcmp(p->name, last_name)>0){
749                 p2= p;
750                 decode= encode= cap=0;
751             }
752             if(p2 && strcmp(p->name, p2->name)==0){
753                 if(p->decode) decode=1;
754                 if(p->encode) encode=1;
755                 cap |= p->capabilities;
756             }
757         }
758         if(p2==NULL)
759             break;
760         last_name= p2->name;
761
762         switch(p2->type) {
763         case AVMEDIA_TYPE_VIDEO:
764             type_str = "V";
765             break;
766         case AVMEDIA_TYPE_AUDIO:
767             type_str = "A";
768             break;
769         case AVMEDIA_TYPE_SUBTITLE:
770             type_str = "S";
771             break;
772         default:
773             type_str = "?";
774             break;
775         }
776         printf(
777             " %s%s%s%s%s%s %-15s %s",
778             decode ? "D": (/*p2->decoder ? "d":*/" "),
779             encode ? "E":" ",
780             type_str,
781             cap & CODEC_CAP_DRAW_HORIZ_BAND ? "S":" ",
782             cap & CODEC_CAP_DR1 ? "D":" ",
783             cap & CODEC_CAP_TRUNCATED ? "T":" ",
784             p2->name,
785             p2->long_name ? p2->long_name : "");
786        /* if(p2->decoder && decode==0)
787             printf(" use %s for decoding", p2->decoder->name);*/
788         printf("\n");
789     }
790     printf("\n");
791     printf(
792 "Note, the names of encoders and decoders do not always match, so there are\n"
793 "several cases where the above table shows encoder only or decoder only entries\n"
794 "even though both encoding and decoding are supported. For example, the h263\n"
795 "decoder corresponds to the h263 and h263p encoders, for file formats it is even\n"
796 "worse.\n");
797     return 0;
798 }
799
800 int opt_bsfs(const char *opt, const char *arg)
801 {
802     AVBitStreamFilter *bsf=NULL;
803
804     printf("Bitstream filters:\n");
805     while((bsf = av_bitstream_filter_next(bsf)))
806         printf("%s\n", bsf->name);
807     printf("\n");
808     return 0;
809 }
810
811 int opt_protocols(const char *opt, const char *arg)
812 {
813     URLProtocol *up=NULL;
814
815     printf("Supported file protocols:\n"
816            "I.. = Input  supported\n"
817            ".O. = Output supported\n"
818            "..S = Seek   supported\n"
819            "FLAGS NAME\n"
820            "----- \n");
821     while((up = av_protocol_next(up)))
822         printf("%c%c%c   %s\n",
823                up->url_read  ? 'I' : '.',
824                up->url_write ? 'O' : '.',
825                up->url_seek  ? 'S' : '.',
826                up->name);
827     return 0;
828 }
829
830 int opt_filters(const char *opt, const char *arg)
831 {
832     AVFilter av_unused(**filter) = NULL;
833
834     printf("Filters:\n");
835 #if CONFIG_AVFILTER
836     while ((filter = av_filter_next(filter)) && *filter)
837         printf("%-16s %s\n", (*filter)->name, (*filter)->description);
838 #endif
839     return 0;
840 }
841
842 int opt_pix_fmts(const char *opt, const char *arg)
843 {
844     enum PixelFormat pix_fmt;
845
846     printf(
847         "Pixel formats:\n"
848         "I.... = Supported Input  format for conversion\n"
849         ".O... = Supported Output format for conversion\n"
850         "..H.. = Hardware accelerated format\n"
851         "...P. = Paletted format\n"
852         "....B = Bitstream format\n"
853         "FLAGS NAME            NB_COMPONENTS BITS_PER_PIXEL\n"
854         "-----\n");
855
856 #if !CONFIG_SWSCALE
857 #   define sws_isSupportedInput(x)  0
858 #   define sws_isSupportedOutput(x) 0
859 #endif
860
861     for (pix_fmt = 0; pix_fmt < PIX_FMT_NB; pix_fmt++) {
862         const AVPixFmtDescriptor *pix_desc = &av_pix_fmt_descriptors[pix_fmt];
863         if(!pix_desc->name)
864             continue;
865         printf("%c%c%c%c%c %-16s       %d            %2d\n",
866                sws_isSupportedInput (pix_fmt)      ? 'I' : '.',
867                sws_isSupportedOutput(pix_fmt)      ? 'O' : '.',
868                pix_desc->flags & PIX_FMT_HWACCEL   ? 'H' : '.',
869                pix_desc->flags & PIX_FMT_PAL       ? 'P' : '.',
870                pix_desc->flags & PIX_FMT_BITSTREAM ? 'B' : '.',
871                pix_desc->name,
872                pix_desc->nb_components,
873                av_get_bits_per_pixel(pix_desc));
874     }
875     return 0;
876 }
877
878 int show_sample_fmts(const char *opt, const char *arg)
879 {
880     int i;
881     char fmt_str[128];
882     for (i = -1; i < AV_SAMPLE_FMT_NB; i++)
883         printf("%s\n", av_get_sample_fmt_string(fmt_str, sizeof(fmt_str), i));
884     return 0;
885 }
886
887 int read_yesno(void)
888 {
889     int c = getchar();
890     int yesno = (toupper(c) == 'Y');
891
892     while (c != '\n' && c != EOF)
893         c = getchar();
894
895     return yesno;
896 }
897
898 int cmdutils_read_file(const char *filename, char **bufptr, size_t *size)
899 {
900     int ret;
901     FILE *f = fopen(filename, "rb");
902
903     if (!f) {
904         av_log(NULL, AV_LOG_ERROR, "Cannot read file '%s': %s\n", filename, strerror(errno));
905         return AVERROR(errno);
906     }
907     fseek(f, 0, SEEK_END);
908     *size = ftell(f);
909     fseek(f, 0, SEEK_SET);
910     *bufptr = av_malloc(*size + 1);
911     if (!*bufptr) {
912         av_log(NULL, AV_LOG_ERROR, "Could not allocate file buffer\n");
913         fclose(f);
914         return AVERROR(ENOMEM);
915     }
916     ret = fread(*bufptr, 1, *size, f);
917     if (ret < *size) {
918         av_free(*bufptr);
919         if (ferror(f)) {
920             av_log(NULL, AV_LOG_ERROR, "Error while reading file '%s': %s\n",
921                    filename, strerror(errno));
922             ret = AVERROR(errno);
923         } else
924             ret = AVERROR_EOF;
925     } else {
926         ret = 0;
927         (*bufptr)[*size++] = '\0';
928     }
929
930     fclose(f);
931     return ret;
932 }
933
934 FILE *get_preset_file(char *filename, size_t filename_size,
935                       const char *preset_name, int is_path, const char *codec_name)
936 {
937     FILE *f = NULL;
938     int i;
939     const char *base[3]= { getenv("FFMPEG_DATADIR"),
940                            getenv("HOME"),
941                            FFMPEG_DATADIR,
942                          };
943
944     if (is_path) {
945         av_strlcpy(filename, preset_name, filename_size);
946         f = fopen(filename, "r");
947     } else {
948 #ifdef _WIN32
949         char datadir[MAX_PATH], *ls;
950         base[2] = NULL;
951
952         if (GetModuleFileNameA(GetModuleHandleA(NULL), datadir, sizeof(datadir) - 1))
953         {
954             for (ls = datadir; ls < datadir + strlen(datadir); ls++)
955                 if (*ls == '\\') *ls = '/';
956
957             if (ls = strrchr(datadir, '/'))
958             {
959                 *ls = 0;
960                 strncat(datadir, "/ffpresets",  sizeof(datadir) - 1 - strlen(datadir));
961                 base[2] = datadir;
962             }
963         }
964 #endif
965         for (i = 0; i < 3 && !f; i++) {
966             if (!base[i])
967                 continue;
968             snprintf(filename, filename_size, "%s%s/%s.ffpreset", base[i], i != 1 ? "" : "/.ffmpeg", preset_name);
969             f = fopen(filename, "r");
970             if (!f && codec_name) {
971                 snprintf(filename, filename_size,
972                          "%s%s/%s-%s.ffpreset", base[i],  i != 1 ? "" : "/.ffmpeg", codec_name, preset_name);
973                 f = fopen(filename, "r");
974             }
975         }
976     }
977
978     return f;
979 }
980
981 int check_stream_specifier(AVFormatContext *s, AVStream *st, const char *spec)
982 {
983     if (*spec <= '9' && *spec >= '0')                                        /* opt:index */
984         return strtol(spec, NULL, 0) == st->index;
985     else if (*spec == 'v' || *spec == 'a' || *spec == 's' || *spec == 'd' || *spec == 't') { /* opt:[vasdt] */
986         enum AVMediaType type;
987
988         switch (*spec++) {
989         case 'v': type = AVMEDIA_TYPE_VIDEO;    break;
990         case 'a': type = AVMEDIA_TYPE_AUDIO;    break;
991         case 's': type = AVMEDIA_TYPE_SUBTITLE; break;
992         case 'd': type = AVMEDIA_TYPE_DATA;     break;
993         case 't': type = AVMEDIA_TYPE_ATTACHMENT; break;
994         default: abort(); // never reached, silence warning
995         }
996         if (type != st->codec->codec_type)
997             return 0;
998         if (*spec++ == ':') {                                   /* possibly followed by :index */
999             int i, index = strtol(spec, NULL, 0);
1000             for (i = 0; i < s->nb_streams; i++)
1001                 if (s->streams[i]->codec->codec_type == type && index-- == 0)
1002                    return i == st->index;
1003             return 0;
1004         }
1005         return 1;
1006     } else if (*spec == 'p' && *(spec + 1) == ':') {
1007         int prog_id, i, j;
1008         char *endptr;
1009         spec += 2;
1010         prog_id = strtol(spec, &endptr, 0);
1011         for (i = 0; i < s->nb_programs; i++) {
1012             if (s->programs[i]->id != prog_id)
1013                 continue;
1014
1015             if (*endptr++ == ':') {
1016                 int stream_idx = strtol(endptr, NULL, 0);
1017                 return (stream_idx >= 0 && stream_idx < s->programs[i]->nb_stream_indexes &&
1018                         st->index == s->programs[i]->stream_index[stream_idx]);
1019             }
1020
1021             for (j = 0; j < s->programs[i]->nb_stream_indexes; j++)
1022                 if (st->index == s->programs[i]->stream_index[j])
1023                     return 1;
1024         }
1025         return 0;
1026     } else if (!*spec) /* empty specifier, matches everything */
1027         return 1;
1028
1029     av_log(s, AV_LOG_ERROR, "Invalid stream specifier: %s.\n", spec);
1030     return AVERROR(EINVAL);
1031 }
1032
1033 AVDictionary *filter_codec_opts(AVDictionary *opts, AVCodec *codec, AVFormatContext *s, AVStream *st)
1034 {
1035     AVDictionary    *ret = NULL;
1036     AVDictionaryEntry *t = NULL;
1037     int            flags = s->oformat ? AV_OPT_FLAG_ENCODING_PARAM : AV_OPT_FLAG_DECODING_PARAM;
1038     char          prefix = 0;
1039     const AVClass    *cc = avcodec_get_class();
1040
1041     if (!codec)
1042         return NULL;
1043
1044     switch (codec->type) {
1045     case AVMEDIA_TYPE_VIDEO:    prefix = 'v'; flags |= AV_OPT_FLAG_VIDEO_PARAM;    break;
1046     case AVMEDIA_TYPE_AUDIO:    prefix = 'a'; flags |= AV_OPT_FLAG_AUDIO_PARAM;    break;
1047     case AVMEDIA_TYPE_SUBTITLE: prefix = 's'; flags |= AV_OPT_FLAG_SUBTITLE_PARAM; break;
1048     }
1049
1050     while (t = av_dict_get(opts, "", t, AV_DICT_IGNORE_SUFFIX)) {
1051         char *p = strchr(t->key, ':');
1052
1053         /* check stream specification in opt name */
1054         if (p)
1055             switch (check_stream_specifier(s, st, p + 1)) {
1056             case  1: *p = 0; break;
1057             case  0:         continue;
1058             default:         return NULL;
1059             }
1060
1061         if (av_opt_find(&cc, t->key, NULL, flags, AV_OPT_SEARCH_FAKE_OBJ) ||
1062             (codec && codec->priv_class && av_opt_find(&codec->priv_class, t->key, NULL, flags, AV_OPT_SEARCH_FAKE_OBJ)))
1063             av_dict_set(&ret, t->key, t->value, 0);
1064         else if (t->key[0] == prefix && av_opt_find(&cc, t->key+1, NULL, flags, AV_OPT_SEARCH_FAKE_OBJ))
1065             av_dict_set(&ret, t->key+1, t->value, 0);
1066
1067         if (p)
1068             *p = ':';
1069     }
1070     return ret;
1071 }
1072
1073 AVDictionary **setup_find_stream_info_opts(AVFormatContext *s, AVDictionary *codec_opts)
1074 {
1075     int i;
1076     AVDictionary **opts;
1077
1078     if (!s->nb_streams)
1079         return NULL;
1080     opts = av_mallocz(s->nb_streams * sizeof(*opts));
1081     if (!opts) {
1082         av_log(NULL, AV_LOG_ERROR, "Could not alloc memory for stream options.\n");
1083         return NULL;
1084     }
1085     for (i = 0; i < s->nb_streams; i++)
1086         opts[i] = filter_codec_opts(codec_opts, avcodec_find_decoder(s->streams[i]->codec->codec_id), s, s->streams[i]);
1087     return opts;
1088 }
1089
1090 void *grow_array(void *array, int elem_size, int *size, int new_size)
1091 {
1092     if (new_size >= INT_MAX / elem_size) {
1093         av_log(NULL, AV_LOG_ERROR, "Array too big.\n");
1094         exit_program(1);
1095     }
1096     if (*size < new_size) {
1097         uint8_t *tmp = av_realloc(array, new_size*elem_size);
1098         if (!tmp) {
1099             av_log(NULL, AV_LOG_ERROR, "Could not alloc buffer.\n");
1100             exit_program(1);
1101         }
1102         memset(tmp + *size*elem_size, 0, (new_size-*size) * elem_size);
1103         *size = new_size;
1104         return tmp;
1105     }
1106     return array;
1107 }