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