cmdutils: replace fprintf() by av_log()
[ffmpeg.git] / cmdutils.c
1 /*
2  * Various utilities for command line tools
3  * Copyright (c) 2000-2003 Fabrice Bellard
4  *
5  * This file is part of Libav.
6  *
7  * Libav is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * Libav is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with Libav; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21
22 #include <string.h>
23 #include <stdlib.h>
24 #include <errno.h>
25 #include <math.h>
26
27 /* Include only the enabled headers since some compilers (namely, Sun
28    Studio) will not omit unused inline functions and create undefined
29    references to libraries that are not being built. */
30
31 #include "config.h"
32 #include "libavformat/avformat.h"
33 #include "libavfilter/avfilter.h"
34 #include "libavdevice/avdevice.h"
35 #include "libswscale/swscale.h"
36 #include "libpostproc/postprocess.h"
37 #include "libavutil/avstring.h"
38 #include "libavutil/parseutils.h"
39 #include "libavutil/pixdesc.h"
40 #include "libavutil/eval.h"
41 #include "libavutil/dict.h"
42 #include "libavutil/opt.h"
43 #include "cmdutils.h"
44 #include "version.h"
45 #if CONFIG_NETWORK
46 #include "libavformat/network.h"
47 #endif
48 #if HAVE_SYS_RESOURCE_H
49 #include <sys/resource.h>
50 #endif
51
52 struct SwsContext *sws_opts;
53 AVDictionary *format_opts, *codec_opts;
54
55 static const int this_year = 2011;
56
57 void init_opts(void)
58 {
59 #if CONFIG_SWSCALE
60     sws_opts = sws_getContext(16, 16, 0, 16, 16, 0, SWS_BICUBIC, NULL, NULL, NULL);
61 #endif
62 }
63
64 void uninit_opts(void)
65 {
66 #if CONFIG_SWSCALE
67     sws_freeContext(sws_opts);
68     sws_opts = NULL;
69 #endif
70     av_dict_free(&format_opts);
71     av_dict_free(&codec_opts);
72 }
73
74 void log_callback_help(void* ptr, int level, const char* fmt, va_list vl)
75 {
76     vfprintf(stdout, fmt, vl);
77 }
78
79 double parse_number_or_die(const char *context, const char *numstr, int type, double min, double max)
80 {
81     char *tail;
82     const char *error;
83     double d = av_strtod(numstr, &tail);
84     if (*tail)
85         error= "Expected number for %s but found: %s\n";
86     else if (d < min || d > max)
87         error= "The value for %s was %s which is not within %f - %f\n";
88     else if(type == OPT_INT64 && (int64_t)d != d)
89         error= "Expected int64 for %s but found %s\n";
90     else if (type == OPT_INT && (int)d != d)
91         error= "Expected int for %s but found %s\n";
92     else
93         return d;
94     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') { /* opt:[vasd] */
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         }
870         if (type != st->codec->codec_type)
871             return 0;
872         if (*spec++ == ':') {                                   /* possibly followed by :index */
873             int i, index = strtol(spec, NULL, 0);
874             for (i = 0; i < s->nb_streams; i++)
875                 if (s->streams[i]->codec->codec_type == type && index-- == 0)
876                    return i == st->index;
877             return 0;
878         }
879         return 1;
880     } else if (*spec == 'p' && *(spec + 1) == ':') {
881         int prog_id, i, j;
882         char *endptr;
883         spec += 2;
884         prog_id = strtol(spec, &endptr, 0);
885         for (i = 0; i < s->nb_programs; i++) {
886             if (s->programs[i]->id != prog_id)
887                 continue;
888
889             if (*endptr++ == ':') {
890                 int stream_idx = strtol(endptr, NULL, 0);
891                 return (stream_idx >= 0 && stream_idx < s->programs[i]->nb_stream_indexes &&
892                         st->index == s->programs[i]->stream_index[stream_idx]);
893             }
894
895             for (j = 0; j < s->programs[i]->nb_stream_indexes; j++)
896                 if (st->index == s->programs[i]->stream_index[j])
897                     return 1;
898         }
899         return 0;
900     } else if (!*spec) /* empty specifier, matches everything */
901         return 1;
902
903     av_log(s, AV_LOG_ERROR, "Invalid stream specifier: %s.\n", spec);
904     return AVERROR(EINVAL);
905 }
906
907 AVDictionary *filter_codec_opts(AVDictionary *opts, enum CodecID codec_id, AVFormatContext *s, AVStream *st)
908 {
909     AVDictionary    *ret = NULL;
910     AVDictionaryEntry *t = NULL;
911     AVCodec       *codec = s->oformat ? avcodec_find_encoder(codec_id) : avcodec_find_decoder(codec_id);
912     int            flags = s->oformat ? AV_OPT_FLAG_ENCODING_PARAM : AV_OPT_FLAG_DECODING_PARAM;
913     char          prefix = 0;
914     const AVClass    *cc = avcodec_get_class();
915
916     if (!codec)
917         return NULL;
918
919     switch (codec->type) {
920     case AVMEDIA_TYPE_VIDEO:    prefix = 'v'; flags |= AV_OPT_FLAG_VIDEO_PARAM;    break;
921     case AVMEDIA_TYPE_AUDIO:    prefix = 'a'; flags |= AV_OPT_FLAG_AUDIO_PARAM;    break;
922     case AVMEDIA_TYPE_SUBTITLE: prefix = 's'; flags |= AV_OPT_FLAG_SUBTITLE_PARAM; break;
923     }
924
925     while (t = av_dict_get(opts, "", t, AV_DICT_IGNORE_SUFFIX)) {
926         char *p = strchr(t->key, ':');
927
928         /* check stream specification in opt name */
929         if (p)
930             switch (check_stream_specifier(s, st, p + 1)) {
931             case  1: *p = 0; break;
932             case  0:         continue;
933             default:         return NULL;
934             }
935
936         if (av_opt_find(&cc, t->key, NULL, flags, AV_OPT_SEARCH_FAKE_OBJ) ||
937             (codec && codec->priv_class && av_opt_find(&codec->priv_class, t->key, NULL, flags, AV_OPT_SEARCH_FAKE_OBJ)))
938             av_dict_set(&ret, t->key, t->value, 0);
939         else if (t->key[0] == prefix && av_opt_find(&cc, t->key+1, NULL, flags, AV_OPT_SEARCH_FAKE_OBJ))
940             av_dict_set(&ret, t->key+1, t->value, 0);
941
942         if (p)
943             *p = ':';
944     }
945     return ret;
946 }
947
948 AVDictionary **setup_find_stream_info_opts(AVFormatContext *s, AVDictionary *codec_opts)
949 {
950     int i;
951     AVDictionary **opts;
952
953     if (!s->nb_streams)
954         return NULL;
955     opts = av_mallocz(s->nb_streams * sizeof(*opts));
956     if (!opts) {
957         av_log(NULL, AV_LOG_ERROR, "Could not alloc memory for stream options.\n");
958         return NULL;
959     }
960     for (i = 0; i < s->nb_streams; i++)
961         opts[i] = filter_codec_opts(codec_opts, s->streams[i]->codec->codec_id, s, s->streams[i]);
962     return opts;
963 }
964
965 #if CONFIG_AVFILTER
966
967 static int ffsink_init(AVFilterContext *ctx, const char *args, void *opaque)
968 {
969     FFSinkContext *priv = ctx->priv;
970
971     if (!opaque)
972         return AVERROR(EINVAL);
973     *priv = *(FFSinkContext *)opaque;
974
975     return 0;
976 }
977
978 static void null_end_frame(AVFilterLink *inlink) { }
979
980 static int ffsink_query_formats(AVFilterContext *ctx)
981 {
982     FFSinkContext *priv = ctx->priv;
983     enum PixelFormat pix_fmts[] = { priv->pix_fmt, PIX_FMT_NONE };
984
985     avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts));
986     return 0;
987 }
988
989 AVFilter ffsink = {
990     .name      = "ffsink",
991     .priv_size = sizeof(FFSinkContext),
992     .init      = ffsink_init,
993
994     .query_formats = ffsink_query_formats,
995
996     .inputs    = (AVFilterPad[]) {{ .name          = "default",
997                                     .type          = AVMEDIA_TYPE_VIDEO,
998                                     .end_frame     = null_end_frame,
999                                     .min_perms     = AV_PERM_READ, },
1000                                   { .name = NULL }},
1001     .outputs   = (AVFilterPad[]) {{ .name = NULL }},
1002 };
1003
1004 int get_filtered_video_frame(AVFilterContext *ctx, AVFrame *frame,
1005                              AVFilterBufferRef **picref_ptr, AVRational *tb)
1006 {
1007     int ret;
1008     AVFilterBufferRef *picref;
1009
1010     if ((ret = avfilter_request_frame(ctx->inputs[0])) < 0)
1011         return ret;
1012     if (!(picref = ctx->inputs[0]->cur_buf))
1013         return AVERROR(ENOENT);
1014     *picref_ptr = picref;
1015     ctx->inputs[0]->cur_buf = NULL;
1016     *tb = ctx->inputs[0]->time_base;
1017
1018     memcpy(frame->data,     picref->data,     sizeof(frame->data));
1019     memcpy(frame->linesize, picref->linesize, sizeof(frame->linesize));
1020     frame->interlaced_frame = picref->video->interlaced;
1021     frame->top_field_first  = picref->video->top_field_first;
1022     frame->key_frame        = picref->video->key_frame;
1023     frame->pict_type        = picref->video->pict_type;
1024
1025     return 1;
1026 }
1027
1028 #endif /* CONFIG_AVFILTER */
1029
1030 void *grow_array(void *array, int elem_size, int *size, int new_size)
1031 {
1032     if (new_size >= INT_MAX / elem_size) {
1033         av_log(NULL, AV_LOG_ERROR, "Array too big.\n");
1034         exit_program(1);
1035     }
1036     if (*size < new_size) {
1037         uint8_t *tmp = av_realloc(array, new_size*elem_size);
1038         if (!tmp) {
1039             av_log(NULL, AV_LOG_ERROR, "Could not alloc buffer.\n");
1040             exit_program(1);
1041         }
1042         memset(tmp + *size*elem_size, 0, (new_size-*size) * elem_size);
1043         *size = new_size;
1044         return tmp;
1045     }
1046     return array;
1047 }