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