]> git.sesse.net Git - ffmpeg/blob - cmdutils.c
Merge remote-tracking branch 'qatar/master'
[ffmpeg] / cmdutils.c
1 /*
2  * Various utilities for command line tools
3  * Copyright (c) 2000-2003 Fabrice Bellard
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg 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  * FFmpeg 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 FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21
22 #include <string.h>
23 #include <stdlib.h>
24 #include <errno.h>
25 #include <math.h>
26
27 /* Include only the enabled headers since some compilers (namely, Sun
28    Studio) will not omit unused inline functions and create undefined
29    references to libraries that are not being built. */
30
31 #include "config.h"
32 #include "libavformat/avformat.h"
33 #include "libavfilter/avfilter.h"
34 #include "libavdevice/avdevice.h"
35 #include "libswscale/swscale.h"
36 #include "libpostproc/postprocess.h"
37 #include "libavutil/avstring.h"
38 #include "libavutil/parseutils.h"
39 #include "libavutil/pixdesc.h"
40 #include "libavutil/eval.h"
41 #include "libavutil/dict.h"
42 #include "libavutil/opt.h"
43 #include "cmdutils.h"
44 #include "version.h"
45 #if CONFIG_NETWORK
46 #include "libavformat/network.h"
47 #endif
48 #if HAVE_SYS_RESOURCE_H
49 #include <sys/resource.h>
50 #endif
51
52 AVCodecContext *avcodec_opts[AVMEDIA_TYPE_NB];
53 AVFormatContext *avformat_opts;
54 struct SwsContext *sws_opts;
55 AVDictionary *format_opts, *codec_opts;
56
57 static const int this_year = 2011;
58
59 void init_opts(void)
60 {
61     int i;
62     for (i = 0; i < AVMEDIA_TYPE_NB; i++)
63         avcodec_opts[i] = avcodec_alloc_context3(NULL);
64     avformat_opts = avformat_alloc_context();
65 #if CONFIG_SWSCALE
66     sws_opts = sws_getContext(16, 16, 0, 16, 16, 0, SWS_BICUBIC, NULL, NULL, NULL);
67 #endif
68 }
69
70 void uninit_opts(void)
71 {
72     int i;
73     for (i = 0; i < AVMEDIA_TYPE_NB; i++)
74         av_freep(&avcodec_opts[i]);
75     av_freep(&avformat_opts->key);
76     av_freep(&avformat_opts);
77 #if CONFIG_SWSCALE
78     sws_freeContext(sws_opts);
79     sws_opts = NULL;
80 #endif
81     av_dict_free(&format_opts);
82     av_dict_free(&codec_opts);
83 }
84
85 void log_callback_help(void* ptr, int level, const char* fmt, va_list vl)
86 {
87     vfprintf(stdout, fmt, vl);
88 }
89
90 double parse_number_or_die(const char *context, const char *numstr, int type, double min, double max)
91 {
92     char *tail;
93     const char *error;
94     double d = av_strtod(numstr, &tail);
95     if (*tail)
96         error= "Expected number for %s but found: %s\n";
97     else if (d < min || d > max)
98         error= "The value for %s was %s which is not within %f - %f\n";
99     else if(type == OPT_INT64 && (int64_t)d != d)
100         error= "Expected int64 for %s but found %s\n";
101     else if (type == OPT_INT && (int)d != d)
102         error= "Expected int for %s but found %s\n";
103     else
104         return d;
105     fprintf(stderr, error, context, numstr, min, max);
106     exit(1);
107 }
108
109 int64_t parse_time_or_die(const char *context, const char *timestr, int is_duration)
110 {
111     int64_t us;
112     if (av_parse_time(&us, timestr, is_duration) < 0) {
113         fprintf(stderr, "Invalid %s specification for %s: %s\n",
114                 is_duration ? "duration" : "date", context, timestr);
115         exit(1);
116     }
117     return us;
118 }
119
120 void show_help_options(const OptionDef *options, const char *msg, int mask, int value)
121 {
122     const OptionDef *po;
123     int first;
124
125     first = 1;
126     for(po = options; po->name != NULL; po++) {
127         char buf[64];
128         if ((po->flags & mask) == value) {
129             if (first) {
130                 printf("%s", msg);
131                 first = 0;
132             }
133             av_strlcpy(buf, po->name, sizeof(buf));
134             if (po->flags & HAS_ARG) {
135                 av_strlcat(buf, " ", sizeof(buf));
136                 av_strlcat(buf, po->argname, sizeof(buf));
137             }
138             printf("-%-17s  %s\n", buf, po->help);
139         }
140     }
141 }
142
143 static const OptionDef* find_option(const OptionDef *po, const char *name){
144     const char *p = strchr(name, ':');
145     int len = p ? p - name : strlen(name);
146
147     while (po->name != NULL) {
148         if (!strncmp(name, po->name, len) && strlen(po->name) == len)
149             break;
150         po++;
151     }
152     return po;
153 }
154
155 #if defined(_WIN32) && !defined(__MINGW32CE__)
156 #include <windows.h>
157 /* Will be leaked on exit */
158 static char** win32_argv_utf8 = NULL;
159 static int win32_argc = 0;
160
161 /**
162  * Prepare command line arguments for executable.
163  * For Windows - perform wide-char to UTF-8 conversion.
164  * Input arguments should be main() function arguments.
165  * @param argc_ptr Arguments number (including executable)
166  * @param argv_ptr Arguments list.
167  */
168 static void prepare_app_arguments(int *argc_ptr, char ***argv_ptr)
169 {
170     char *argstr_flat;
171     wchar_t **argv_w;
172     int i, buffsize = 0, offset = 0;
173
174     if (win32_argv_utf8) {
175         *argc_ptr = win32_argc;
176         *argv_ptr = win32_argv_utf8;
177         return;
178     }
179
180     win32_argc = 0;
181     argv_w = CommandLineToArgvW(GetCommandLineW(), &win32_argc);
182     if (win32_argc <= 0 || !argv_w)
183         return;
184
185     /* determine the UTF-8 buffer size (including NULL-termination symbols) */
186     for (i = 0; i < win32_argc; i++)
187         buffsize += WideCharToMultiByte(CP_UTF8, 0, argv_w[i], -1,
188                                         NULL, 0, NULL, NULL);
189
190     win32_argv_utf8 = av_mallocz(sizeof(char*) * (win32_argc + 1) + buffsize);
191     argstr_flat     = (char*)win32_argv_utf8 + sizeof(char*) * (win32_argc + 1);
192     if (win32_argv_utf8 == NULL) {
193         LocalFree(argv_w);
194         return;
195     }
196
197     for (i = 0; i < win32_argc; i++) {
198         win32_argv_utf8[i] = &argstr_flat[offset];
199         offset += WideCharToMultiByte(CP_UTF8, 0, argv_w[i], -1,
200                                       &argstr_flat[offset],
201                                       buffsize - offset, NULL, NULL);
202     }
203     win32_argv_utf8[i] = NULL;
204     LocalFree(argv_w);
205
206     *argc_ptr = win32_argc;
207     *argv_ptr = win32_argv_utf8;
208 }
209 #else
210 static inline void prepare_app_arguments(int *argc_ptr, char ***argv_ptr)
211 {
212     /* nothing to do */
213 }
214 #endif /* WIN32 && !__MINGW32CE__ */
215
216 void parse_options(int argc, char **argv, const OptionDef *options,
217                    int (* parse_arg_function)(const char *opt, const char *arg))
218 {
219     const char *opt, *arg;
220     int optindex, handleoptions=1;
221     const OptionDef *po;
222
223     /* perform system-dependent conversions for arguments list */
224     prepare_app_arguments(&argc, &argv);
225
226     /* parse options */
227     optindex = 1;
228     while (optindex < argc) {
229         opt = argv[optindex++];
230
231         if (handleoptions && opt[0] == '-' && opt[1] != '\0') {
232             int bool_val = 1;
233             if (opt[1] == '-' && opt[2] == '\0') {
234                 handleoptions = 0;
235                 continue;
236             }
237             opt++;
238             po= find_option(options, opt);
239             if (!po->name && opt[0] == 'n' && opt[1] == 'o') {
240                 /* handle 'no' bool option */
241                 po = find_option(options, opt + 2);
242                 if (!(po->name && (po->flags & OPT_BOOL)))
243                     goto unknown_opt;
244                 bool_val = 0;
245             }
246             if (!po->name)
247                 po= find_option(options, "default");
248             if (!po->name) {
249 unknown_opt:
250                 fprintf(stderr, "%s: unrecognized option '%s'\n", argv[0], opt);
251                 exit(1);
252             }
253             arg = NULL;
254             if (po->flags & HAS_ARG) {
255                 arg = argv[optindex++];
256                 if (!arg) {
257                     fprintf(stderr, "%s: missing argument for option '%s'\n", argv[0], opt);
258                     exit(1);
259                 }
260             }
261             if (po->flags & OPT_STRING) {
262                 char *str;
263                 str = av_strdup(arg);
264                 *po->u.str_arg = str;
265             } else if (po->flags & OPT_BOOL) {
266                 *po->u.int_arg = bool_val;
267             } else if (po->flags & OPT_INT) {
268                 *po->u.int_arg = parse_number_or_die(opt, arg, OPT_INT64, INT_MIN, INT_MAX);
269             } else if (po->flags & OPT_INT64) {
270                 *po->u.int64_arg = parse_number_or_die(opt, arg, OPT_INT64, INT64_MIN, INT64_MAX);
271             } else if (po->flags & OPT_FLOAT) {
272                 *po->u.float_arg = parse_number_or_die(opt, arg, OPT_FLOAT, -INFINITY, INFINITY);
273             } else if (po->u.func_arg) {
274                 if (po->u.func_arg(opt, arg) < 0) {
275                     fprintf(stderr, "%s: failed to set value '%s' for option '%s'\n", argv[0], arg ? arg : "[null]", opt);
276                     exit(1);
277                 }
278             }
279             if(po->flags & OPT_EXIT)
280                 exit(0);
281         } else {
282             if (parse_arg_function) {
283                 if (parse_arg_function(NULL, opt) < 0)
284                     exit(1);
285             }
286         }
287     }
288 }
289
290 #define FLAGS(o) ((o)->type == FF_OPT_TYPE_FLAGS) ? AV_DICT_APPEND : 0
291 int opt_default(const char *opt, const char *arg)
292 {
293     const AVOption *oc, *of, *os;
294     char opt_stripped[128];
295     const char *p;
296
297     if (!(p = strchr(opt, ':')))
298         p = opt + strlen(opt);
299     av_strlcpy(opt_stripped, opt, FFMIN(sizeof(opt_stripped), p - opt + 1));
300
301     if ((oc = av_opt_find(avcodec_opts[0], opt_stripped, NULL, 0, AV_OPT_SEARCH_CHILDREN)) ||
302          ((opt[0] == 'v' || opt[0] == 'a' || opt[0] == 's') &&
303           (oc = av_opt_find(avcodec_opts[0], opt+1, NULL, 0, 0))))
304         av_dict_set(&codec_opts, opt, arg, FLAGS(oc));
305     if ((of = av_opt_find(avformat_opts, opt, NULL, 0, AV_OPT_SEARCH_CHILDREN)))
306         av_dict_set(&format_opts, opt, arg, FLAGS(of));
307     if ((os = av_opt_find(sws_opts, opt, NULL, 0, AV_OPT_SEARCH_CHILDREN))) {
308         // XXX we only support sws_flags, not arbitrary sws options
309         int ret = av_set_string3(sws_opts, opt, arg, 1, NULL);
310         if (ret < 0) {
311             av_log(NULL, AV_LOG_ERROR, "Error setting option %s.\n", opt);
312             return ret;
313         }
314     }
315
316     if (oc || of || os)
317         return 0;
318     fprintf(stderr, "Unrecognized option '%s'\n", opt);
319     return AVERROR_OPTION_NOT_FOUND;
320 }
321
322 int opt_loglevel(const char *opt, const char *arg)
323 {
324     const struct { const char *name; int level; } log_levels[] = {
325         { "quiet"  , AV_LOG_QUIET   },
326         { "panic"  , AV_LOG_PANIC   },
327         { "fatal"  , AV_LOG_FATAL   },
328         { "error"  , AV_LOG_ERROR   },
329         { "warning", AV_LOG_WARNING },
330         { "info"   , AV_LOG_INFO    },
331         { "verbose", AV_LOG_VERBOSE },
332         { "debug"  , AV_LOG_DEBUG   },
333     };
334     char *tail;
335     int level;
336     int i;
337
338     for (i = 0; i < FF_ARRAY_ELEMS(log_levels); i++) {
339         if (!strcmp(log_levels[i].name, arg)) {
340             av_log_set_level(log_levels[i].level);
341             return 0;
342         }
343     }
344
345     level = strtol(arg, &tail, 10);
346     if (*tail) {
347         fprintf(stderr, "Invalid loglevel \"%s\". "
348                         "Possible levels are numbers or:\n", arg);
349         for (i = 0; i < FF_ARRAY_ELEMS(log_levels); i++)
350             fprintf(stderr, "\"%s\"\n", log_levels[i].name);
351         exit(1);
352     }
353     av_log_set_level(level);
354     return 0;
355 }
356
357 int opt_timelimit(const char *opt, const char *arg)
358 {
359 #if HAVE_SETRLIMIT
360     int lim = parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX);
361     struct rlimit rl = { lim, lim + 1 };
362     if (setrlimit(RLIMIT_CPU, &rl))
363         perror("setrlimit");
364 #else
365     fprintf(stderr, "Warning: -%s not implemented on this OS\n", opt);
366 #endif
367     return 0;
368 }
369
370 void print_error(const char *filename, int err)
371 {
372     char errbuf[128];
373     const char *errbuf_ptr = errbuf;
374
375     if (av_strerror(err, errbuf, sizeof(errbuf)) < 0)
376         errbuf_ptr = strerror(AVUNERROR(err));
377     fprintf(stderr, "%s: %s\n", filename, errbuf_ptr);
378 }
379
380 static int warned_cfg = 0;
381
382 #define INDENT        1
383 #define SHOW_VERSION  2
384 #define SHOW_CONFIG   4
385
386 #define PRINT_LIB_INFO(outstream,libname,LIBNAME,flags)                 \
387     if (CONFIG_##LIBNAME) {                                             \
388         const char *indent = flags & INDENT? "  " : "";                 \
389         if (flags & SHOW_VERSION) {                                     \
390             unsigned int version = libname##_version();                 \
391             fprintf(outstream, "%slib%-9s %2d.%3d.%2d / %2d.%3d.%2d\n", \
392                     indent, #libname,                                   \
393                     LIB##LIBNAME##_VERSION_MAJOR,                       \
394                     LIB##LIBNAME##_VERSION_MINOR,                       \
395                     LIB##LIBNAME##_VERSION_MICRO,                       \
396                     version >> 16, version >> 8 & 0xff, version & 0xff); \
397         }                                                               \
398         if (flags & SHOW_CONFIG) {                                      \
399             const char *cfg = libname##_configuration();                \
400             if (strcmp(FFMPEG_CONFIGURATION, cfg)) {                    \
401                 if (!warned_cfg) {                                      \
402                     fprintf(outstream,                                  \
403                             "%sWARNING: library configuration mismatch\n", \
404                             indent);                                    \
405                     warned_cfg = 1;                                     \
406                 }                                                       \
407                 fprintf(stderr, "%s%-11s configuration: %s\n",          \
408                         indent, #libname, cfg);                         \
409             }                                                           \
410         }                                                               \
411     }                                                                   \
412
413 static void print_all_libs_info(FILE* outstream, int flags)
414 {
415     PRINT_LIB_INFO(outstream, avutil,   AVUTIL,   flags);
416     PRINT_LIB_INFO(outstream, avcodec,  AVCODEC,  flags);
417     PRINT_LIB_INFO(outstream, avformat, AVFORMAT, flags);
418     PRINT_LIB_INFO(outstream, avdevice, AVDEVICE, flags);
419     PRINT_LIB_INFO(outstream, avfilter, AVFILTER, flags);
420     PRINT_LIB_INFO(outstream, swscale,  SWSCALE,  flags);
421     PRINT_LIB_INFO(outstream, postproc, POSTPROC, flags);
422 }
423
424 void show_banner(void)
425 {
426     fprintf(stderr, "%s version " FFMPEG_VERSION ", Copyright (c) %d-%d the FFmpeg developers\n",
427             program_name, program_birth_year, this_year);
428     fprintf(stderr, "  built on %s %s with %s %s\n",
429             __DATE__, __TIME__, CC_TYPE, CC_VERSION);
430     fprintf(stderr, "  configuration: " FFMPEG_CONFIGURATION "\n");
431     print_all_libs_info(stderr, INDENT|SHOW_CONFIG);
432     print_all_libs_info(stderr, INDENT|SHOW_VERSION);
433 }
434
435 int opt_version(const char *opt, const char *arg) {
436     printf("%s " FFMPEG_VERSION "\n", program_name);
437     print_all_libs_info(stdout, SHOW_VERSION);
438     return 0;
439 }
440
441 int opt_license(const char *opt, const char *arg)
442 {
443     printf(
444 #if CONFIG_NONFREE
445     "This version of %s has nonfree parts compiled in.\n"
446     "Therefore it is not legally redistributable.\n",
447     program_name
448 #elif CONFIG_GPLV3
449     "%s is free software; you can redistribute it and/or modify\n"
450     "it under the terms of the GNU General Public License as published by\n"
451     "the Free Software Foundation; either version 3 of the License, or\n"
452     "(at your option) any later version.\n"
453     "\n"
454     "%s is distributed in the hope that it will be useful,\n"
455     "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
456     "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
457     "GNU General Public License for more details.\n"
458     "\n"
459     "You should have received a copy of the GNU General Public License\n"
460     "along with %s.  If not, see <http://www.gnu.org/licenses/>.\n",
461     program_name, program_name, program_name
462 #elif CONFIG_GPL
463     "%s is free software; you can redistribute it and/or modify\n"
464     "it under the terms of the GNU General Public License as published by\n"
465     "the Free Software Foundation; either version 2 of the License, or\n"
466     "(at your option) any later version.\n"
467     "\n"
468     "%s is distributed in the hope that it will be useful,\n"
469     "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
470     "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
471     "GNU General Public License for more details.\n"
472     "\n"
473     "You should have received a copy of the GNU General Public License\n"
474     "along with %s; if not, write to the Free Software\n"
475     "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n",
476     program_name, program_name, program_name
477 #elif CONFIG_LGPLV3
478     "%s is free software; you can redistribute it and/or modify\n"
479     "it under the terms of the GNU Lesser General Public License as published by\n"
480     "the Free Software Foundation; either version 3 of the License, or\n"
481     "(at your option) any later version.\n"
482     "\n"
483     "%s is distributed in the hope that it will be useful,\n"
484     "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
485     "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
486     "GNU Lesser General Public License for more details.\n"
487     "\n"
488     "You should have received a copy of the GNU Lesser General Public License\n"
489     "along with %s.  If not, see <http://www.gnu.org/licenses/>.\n",
490     program_name, program_name, program_name
491 #else
492     "%s is free software; you can redistribute it and/or\n"
493     "modify it under the terms of the GNU Lesser General Public\n"
494     "License as published by the Free Software Foundation; either\n"
495     "version 2.1 of the License, or (at your option) any later version.\n"
496     "\n"
497     "%s is distributed in the hope that it will be useful,\n"
498     "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
499     "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n"
500     "Lesser General Public License for more details.\n"
501     "\n"
502     "You should have received a copy of the GNU Lesser General Public\n"
503     "License along with %s; if not, write to the Free Software\n"
504     "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n",
505     program_name, program_name, program_name
506 #endif
507     );
508     return 0;
509 }
510
511 int opt_formats(const char *opt, const char *arg)
512 {
513     AVInputFormat *ifmt=NULL;
514     AVOutputFormat *ofmt=NULL;
515     const char *last_name;
516
517     printf(
518         "File formats:\n"
519         " D. = Demuxing supported\n"
520         " .E = Muxing supported\n"
521         " --\n");
522     last_name= "000";
523     for(;;){
524         int decode=0;
525         int encode=0;
526         const char *name=NULL;
527         const char *long_name=NULL;
528
529         while((ofmt= av_oformat_next(ofmt))) {
530             if((name == NULL || strcmp(ofmt->name, name)<0) &&
531                 strcmp(ofmt->name, last_name)>0){
532                 name= ofmt->name;
533                 long_name= ofmt->long_name;
534                 encode=1;
535             }
536         }
537         while((ifmt= av_iformat_next(ifmt))) {
538             if((name == NULL || strcmp(ifmt->name, name)<0) &&
539                 strcmp(ifmt->name, last_name)>0){
540                 name= ifmt->name;
541                 long_name= ifmt->long_name;
542                 encode=0;
543             }
544             if(name && strcmp(ifmt->name, name)==0)
545                 decode=1;
546         }
547         if(name==NULL)
548             break;
549         last_name= name;
550
551         printf(
552             " %s%s %-15s %s\n",
553             decode ? "D":" ",
554             encode ? "E":" ",
555             name,
556             long_name ? long_name:" ");
557     }
558     return 0;
559 }
560
561 int opt_codecs(const char *opt, const char *arg)
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     return 0;
636 }
637
638 int opt_bsfs(const char *opt, const char *arg)
639 {
640     AVBitStreamFilter *bsf=NULL;
641
642     printf("Bitstream filters:\n");
643     while((bsf = av_bitstream_filter_next(bsf)))
644         printf("%s\n", bsf->name);
645     printf("\n");
646     return 0;
647 }
648
649 int opt_protocols(const char *opt, const char *arg)
650 {
651     URLProtocol *up=NULL;
652
653     printf("Supported file protocols:\n"
654            "I.. = Input  supported\n"
655            ".O. = Output supported\n"
656            "..S = Seek   supported\n"
657            "FLAGS NAME\n"
658            "----- \n");
659     while((up = av_protocol_next(up)))
660         printf("%c%c%c   %s\n",
661                up->url_read  ? 'I' : '.',
662                up->url_write ? 'O' : '.',
663                up->url_seek  ? 'S' : '.',
664                up->name);
665     return 0;
666 }
667
668 int opt_filters(const char *opt, const char *arg)
669 {
670     AVFilter av_unused(**filter) = NULL;
671
672     printf("Filters:\n");
673 #if CONFIG_AVFILTER
674     while ((filter = av_filter_next(filter)) && *filter)
675         printf("%-16s %s\n", (*filter)->name, (*filter)->description);
676 #endif
677     return 0;
678 }
679
680 int opt_pix_fmts(const char *opt, const char *arg)
681 {
682     enum PixelFormat pix_fmt;
683
684     printf(
685         "Pixel formats:\n"
686         "I.... = Supported Input  format for conversion\n"
687         ".O... = Supported Output format for conversion\n"
688         "..H.. = Hardware accelerated format\n"
689         "...P. = Paletted format\n"
690         "....B = Bitstream format\n"
691         "FLAGS NAME            NB_COMPONENTS BITS_PER_PIXEL\n"
692         "-----\n");
693
694 #if !CONFIG_SWSCALE
695 #   define sws_isSupportedInput(x)  0
696 #   define sws_isSupportedOutput(x) 0
697 #endif
698
699     for (pix_fmt = 0; pix_fmt < PIX_FMT_NB; pix_fmt++) {
700         const AVPixFmtDescriptor *pix_desc = &av_pix_fmt_descriptors[pix_fmt];
701         printf("%c%c%c%c%c %-16s       %d            %2d\n",
702                sws_isSupportedInput (pix_fmt)      ? 'I' : '.',
703                sws_isSupportedOutput(pix_fmt)      ? 'O' : '.',
704                pix_desc->flags & PIX_FMT_HWACCEL   ? 'H' : '.',
705                pix_desc->flags & PIX_FMT_PAL       ? 'P' : '.',
706                pix_desc->flags & PIX_FMT_BITSTREAM ? 'B' : '.',
707                pix_desc->name,
708                pix_desc->nb_components,
709                av_get_bits_per_pixel(pix_desc));
710     }
711     return 0;
712 }
713
714 int read_yesno(void)
715 {
716     int c = getchar();
717     int yesno = (toupper(c) == 'Y');
718
719     while (c != '\n' && c != EOF)
720         c = getchar();
721
722     return yesno;
723 }
724
725 int read_file(const char *filename, char **bufptr, size_t *size)
726 {
727     FILE *f = fopen(filename, "rb");
728
729     if (!f) {
730         fprintf(stderr, "Cannot read file '%s': %s\n", filename, strerror(errno));
731         return AVERROR(errno);
732     }
733     fseek(f, 0, SEEK_END);
734     *size = ftell(f);
735     fseek(f, 0, SEEK_SET);
736     *bufptr = av_malloc(*size + 1);
737     if (!*bufptr) {
738         fprintf(stderr, "Could not allocate file buffer\n");
739         fclose(f);
740         return AVERROR(ENOMEM);
741     }
742     fread(*bufptr, 1, *size, f);
743     (*bufptr)[*size++] = '\0';
744
745     fclose(f);
746     return 0;
747 }
748
749 FILE *get_preset_file(char *filename, size_t filename_size,
750                       const char *preset_name, int is_path, const char *codec_name)
751 {
752     FILE *f = NULL;
753     int i;
754     const char *base[3]= { getenv("AVCONV_DATADIR"),
755                            getenv("HOME"),
756                            AVCONV_DATADIR,
757                          };
758
759     if (is_path) {
760         av_strlcpy(filename, preset_name, filename_size);
761         f = fopen(filename, "r");
762     } else {
763 #ifdef _WIN32
764         char datadir[MAX_PATH], *ls;
765         base[2] = NULL;
766
767         if (GetModuleFileNameA(GetModuleHandleA(NULL), datadir, sizeof(datadir) - 1))
768         {
769             for (ls = datadir; ls < datadir + strlen(datadir); ls++)
770                 if (*ls == '\\') *ls = '/';
771
772             if (ls = strrchr(datadir, '/'))
773             {
774                 *ls = 0;
775                 strncat(datadir, "/ffpresets",  sizeof(datadir) - 1 - strlen(datadir));
776                 base[2] = datadir;
777             }
778         }
779 #endif
780         for (i = 0; i < 3 && !f; i++) {
781             if (!base[i])
782                 continue;
783             snprintf(filename, filename_size, "%s%s/%s.ffpreset", base[i], i != 1 ? "" : "/.avconv", preset_name);
784             f = fopen(filename, "r");
785             if (!f && codec_name) {
786                 snprintf(filename, filename_size,
787                          "%s%s/%s-%s.ffpreset", base[i],  i != 1 ? "" : "/.avconv", codec_name, preset_name);
788                 f = fopen(filename, "r");
789             }
790         }
791     }
792
793     return f;
794 }
795
796 int check_stream_specifier(AVFormatContext *s, AVStream *st, const char *spec)
797 {
798     if (*spec <= '9' && *spec >= '0')                                        /* opt:index */
799         return strtol(spec, NULL, 0) == st->index;
800     else if (*spec == 'v' || *spec == 'a' || *spec == 's' || *spec == 'd') { /* opt:[vasd] */
801         enum AVMediaType type;
802
803         switch (*spec++) {
804         case 'v': type = AVMEDIA_TYPE_VIDEO;    break;
805         case 'a': type = AVMEDIA_TYPE_AUDIO;    break;
806         case 's': type = AVMEDIA_TYPE_SUBTITLE; break;
807         case 'd': type = AVMEDIA_TYPE_DATA;     break;
808         }
809         if (type != st->codec->codec_type)
810             return 0;
811         if (*spec++ == ':') {                                   /* possibly followed by :index */
812             int i, index = strtol(spec, NULL, 0);
813             for (i = 0; i < s->nb_streams; i++)
814                 if (s->streams[i]->codec->codec_type == type && index-- == 0)
815                    return i == st->index;
816             return 0;
817         }
818         return 1;
819     } else if (!*spec) /* empty specifier, matches everything */
820         return 1;
821
822     av_log(s, AV_LOG_ERROR, "Invalid stream specifier: %s.\n", spec);
823     return AVERROR(EINVAL);
824 }
825
826 AVDictionary *filter_codec_opts(AVDictionary *opts, enum CodecID codec_id, AVFormatContext *s, AVStream *st)
827 {
828     AVDictionary    *ret = NULL;
829     AVDictionaryEntry *t = NULL;
830     AVCodec       *codec = s->oformat ? avcodec_find_encoder(codec_id) : avcodec_find_decoder(codec_id);
831     int            flags = s->oformat ? AV_OPT_FLAG_ENCODING_PARAM : AV_OPT_FLAG_DECODING_PARAM;
832     char          prefix = 0;
833
834     if (!codec)
835         return NULL;
836
837     switch (codec->type) {
838     case AVMEDIA_TYPE_VIDEO:    prefix = 'v'; flags |= AV_OPT_FLAG_VIDEO_PARAM;    break;
839     case AVMEDIA_TYPE_AUDIO:    prefix = 'a'; flags |= AV_OPT_FLAG_AUDIO_PARAM;    break;
840     case AVMEDIA_TYPE_SUBTITLE: prefix = 's'; flags |= AV_OPT_FLAG_SUBTITLE_PARAM; break;
841     }
842
843     while (t = av_dict_get(opts, "", t, AV_DICT_IGNORE_SUFFIX)) {
844         char *p = strchr(t->key, ':');
845
846         /* check stream specification in opt name */
847         if (p)
848             switch (check_stream_specifier(s, st, p + 1)) {
849             case  1: *p = 0; break;
850             case  0:         continue;
851             default:         return NULL;
852             }
853
854         if (av_opt_find(avcodec_opts[0], t->key, NULL, flags, 0) ||
855             (codec && codec->priv_class && av_opt_find(&codec->priv_class, t->key, NULL, flags, 0)))
856             av_dict_set(&ret, t->key, t->value, 0);
857         else if (t->key[0] == prefix && av_opt_find(avcodec_opts[0], t->key+1, NULL, flags, 0))
858             av_dict_set(&ret, t->key+1, t->value, 0);
859
860         if (p)
861             *p = ':';
862     }
863     return ret;
864 }
865
866 AVDictionary **setup_find_stream_info_opts(AVFormatContext *s, AVDictionary *codec_opts)
867 {
868     int i;
869     AVDictionary **opts;
870
871     if (!s->nb_streams)
872         return NULL;
873     opts = av_mallocz(s->nb_streams * sizeof(*opts));
874     if (!opts) {
875         av_log(NULL, AV_LOG_ERROR, "Could not alloc memory for stream options.\n");
876         return NULL;
877     }
878     for (i = 0; i < s->nb_streams; i++)
879         opts[i] = filter_codec_opts(codec_opts, s->streams[i]->codec->codec_id, s, s->streams[i]);
880     return opts;
881 }
882