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