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