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