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