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