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