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