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