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