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