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